Java 21 / Spring Boot / Netty game server framework for building real-time game backends with a custom WS binary protocol, annotation-based routing, sharded execution, reliable push/resume, observability, and service discovery.
This repository contains framework/runtime code only (no gameplay/business logic).
License: Apache-2.0 (see LICENSE).
- Netty-only message pipeline (no Spring MVC/Tomcat in the hot path)
- Custom protocol: WebSocket Binary + TLV envelope (extensible, skip-unknown) + Protobuf payload
- Req/Resp with dedup-friendly
seq(server-side dedup + timeout), plus reliable push withACK_REQUIRED+ resume window - Sharded execution model for game state (by
playerId/ channel) - Optional Prometheus metrics + OpenTelemetry tracing
- Nacos-based service discovery + gRPC/IPC integration points
flowchart LR
subgraph Client
U[Unity SDK]:::c
T[TS SDK - Cocos/LayaAir]:::c
end
U -->|WS Binary + TLV| WS
T -->|WS Binary + TLV| WS
subgraph GameGateway["Game Gateway - Netty"]
WS[Netty WebSocket Server]:::s
DEC[TLV Frame Decoder/Encoder]:::s
DISP[Dispatcher Runtime - @GameController/@GameRoute]:::s
SHARD[Shard Executor - player/channel]:::s
SCHED[HashedWheel Scheduler]:::s
end
WS --> DEC --> DISP --> SHARD
SHARD -->|invoke handler| H[Game Handlers - your code]:::a
H -->|RESP/PUSH| DISP
SCHED --> SHARD
subgraph Infra["Infra"]
NACOS[Nacos Registry/Discovery]:::i
GRPC[gRPC / IPC endpoints]:::i
OBS[Prometheus / OTel]:::i
JOBS[Jobs Runner - local + leader-only SPI]:::i
end
DISP --- OBS
WS --- OBS
JOBS --- OBS
DISP --- GRPC
GRPC --- NACOS
classDef c fill:#1f2937,stroke:#0b1220,color:#ffffff
classDef s fill:#0ea5e9,stroke:#075985,color:#ffffff
classDef a fill:#22c55e,stroke:#15803d,color:#ffffff
classDef i fill:#a855f7,stroke:#6b21a8,color:#ffffff
.
├── civgenesis-core/ # protocol, errors, sharded executors, observability SPI
├── civgenesis-codec-tlv/ # TLV varint codec
├── civgenesis-protocol-system/ # system.proto (reserved msgId range)
├── civgenesis-codec-protobuf/ # protobuf payload codec + system Error
├── civgenesis-dispatcher/ # @GameController/@GameRoute + route scan + dispatcher runtime
├── civgenesis-scheduler/ # hashed wheel scheduler (time wheel)
├── civgenesis-transport-netty-ws/ # Netty WebSocket transport
├── civgenesis-transport-netty-tcp/ # Netty TCP transport (length-prefixed)
├── civgenesis-registry/ # registry/discovery SPI
├── civgenesis-registry-nacos/ # Nacos implementation
├── civgenesis-rpc-grpc/ # gRPC helpers
├── civgenesis-jobs/ # background jobs (local + leader-only lease SPI)
├── civgenesis-jobs-lease-redis/ # optional Redis LeaseProvider reference impl
├── civgenesis-ipc/ # IPC reference impl (UDS) + InstanceId helpers
├── civgenesis-ipc-aeron/ # IPC reference impl (Aeron IPC / SHM)
├── civgenesis-spring-boot-starter/ # auto-wiring (no MVC), properties, lifecycle
├── clients/
│ ├── unity/ # Unity (C#) client SDK (protocol + connection mgmt)
│ └── ts/ # TypeScript client SDK (Cocos/LayaAir)
├── examples/
│ └── echo-server/ # minimal server example (no gameplay logic)
└── docs/ # VuePress docs (published via GitHub Pages)
- Keep the hot path minimal: Netty -> decode -> dispatch -> shard -> handler
- Prefer deterministic state handling: shard by
playerIdfor ordered execution - Treat reliability as a protocol feature:
seqfor Req/Resp retries;pushId+ACK_REQUIREDfor reliable push - Prefer “resume window, else full sync”: small gap replay, large gap snapshot
- Observability is opt-in but first-class: metrics & tracing should be cheap when disabled
Spring Boot is used for wiring/lifecycle only. Game messages do not go through Spring MVC.
- Add dependency (your app)
dependencies {
implementation("io.github.cuihairu:civgenesis-spring-boot-starter:<version>")
}- Write routes
@GameController
public class EchoController {
@GameRoute(id = 1000, open = true)
public void echo(RequestContext ctx, EchoReq req) {
ctx.reply(EchoResp.newBuilder().setText(req.getText()).build());
}
}- Provide system integrations (required)
- Implement token authentication for
Resume:- SPI:
io.github.cuihairu.civgenesis.system.auth.TokenAuthenticator
- SPI:
- Implement snapshot generation for
SyncSnapshot(recommended):- SPI:
io.github.cuihairu.civgenesis.system.snapshot.SnapshotProvider
- SPI:
- Configure
civgenesis:
dispatcher:
enabled: true
shards: 64
ws:
enabled: true
port: 8080
path: /ws- Docs index:
docs/README.md - Quickstart (example app):
docs/QUICKSTART.md - GitHub Pages (CI published):
https://cuihairu.github.io/civgenesis/ - Protocol:
docs/PROTOCOL.md - Protobuf workflow:
docs/PROTOBUF.md - Dispatcher/routing:
docs/DISPATCHER.md - Observability:
docs/OBSERVABILITY.md - Jobs (local/distributed):
docs/JOBS.md - Client SDKs:
docs/CLIENT_SDK.md - Integration (admin/gateway/login):
docs/INTEGRATION.md
- Unity(C#):
clients/unity/ - TypeScript(Cocos/LayaAir):
clients/ts/
./gradlew buildLocal preview:
npm ci
npm run docs:devBuild static site:
npm ci
npm run docs:build