All-in-One Solution for Indie Game Development · Empowering Indie Developers' Dreams
📖 Documentation · 🚀 Quick Start · 💬 QQ Group: 467608841
🌐 Language: English | 简体中文 | 繁體中文 | 日本語 | 한국어
Make a game with GameFrameX — this repo is the official GameFrameX game repository: it consumes the framework via the 2.0 NuGet packages, ships a living demo of the shortest closed loop (server boot → matchmaking → match → settlement → leaderboard, with ConnectFour bridged onto the Online capabilities), and doubles as the starting template for your own game. The framework itself (the distribution packages) evolves in the Server.Source framework repo; this repo drives its backlog through issues and sample requests — code is never copied backwards.
Design Philosophy: Simplicity over complexity
- Actor Model — Lock-free high-concurrency architecture based on TPL DataFlow, avoiding traditional lock contention through message passing
- State-Logic Separation — Strict separation between persistent data (Apps layer) and hot-updatable business logic (Hotfix layer)
- Zero-Downtime Hot Updates — Replace business logic assemblies at runtime without restarting the server
- Multi-Protocol Networking — Support for TCP, WebSocket, and HTTP protocols with built-in message encoding/decoding and compression
- MongoDB Persistence — Transparent ORM mapping based on CacheState with automatic serialization/deserialization
- Source Generator — Roslyn-based Agent code generation for automatic Actor message queue scheduling
- Config Table System — Integrated Luban config generation with JSON hot-reloading
- OpenTelemetry — Built-in Prometheus metrics export, health checks, and performance monitoring
┌──────────────────────────────────────────────────────────────┐
│ Client Layer │
├──────────────────────────────────────────────────────────────┤
│ Network Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ TCP │ │WebSocket │ │ HTTP │ │ KCP │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├──────────────────────────────────────────────────────────────┤
│ Hotfix Layer (Hot-updatable) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ ComponentAgent │ HttpHandler │ EventHandler │ │
│ └──────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ Apps Layer (Non-hot-updatable) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ State │ │Component │ │ActorType │ │
│ └──────────┘ └──────────┘ └──────────┘ │
├──────────────────────────────────────────────────────────────┤
│ Framework Layer (NuGet Packages) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Core │ │ NetWork │ │ DataBase │ │ Monitor │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├──────────────────────────────────────────────────────────────┤
│ Database Layer │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ MongoDB │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
| Dependency | Version |
|---|---|
| .NET SDK | 10.0+ |
| MongoDB | 4.x+ |
| IDE | Visual Studio 2022 / JetBrains Rider / VS Code |
Local development defaults:
- Prefer opening
Server.slnx. It is smaller and easier to review. If your IDE does not support.slnx, openServer.sln. - For normal local debugging, leave
Program arguments/Command line argumentsempty. Defaults are defined inGameFrameX.Launcher/StartUp/AppStartUpGame.cs. - Use startup arguments only when you need to override those defaults, such as changing ports or using another MongoDB instance.
git clone https://github.com/GameFrameX/Server_main.git
cd Server_main
docker compose up -d --buildStart MongoDB first:
docker compose up -d mongodb
Then build and run the launcher from the output directory:
NuGet source note (pre-release): the GameFrameX 2.0 packages are not yet published on nuget.org. The root
nuget.configtherefore adds aGameFrameX-Internalsource pointing at the sibling directory../LocalPackages(internal verification feed). A plain clone without that feed fails to restore withNU1301— either put the GameFrameX 2.0.0 packages into a siblingLocalPackagesfolder, or repoint that source to your own feed. Publication to nuget.org is tracked in the framework repo backlog.
git clone https://github.com/GameFrameX/Server_main.git cd Server_main dotnet restore dotnet build Server.sln cd bin/app_debug dotnet GameFrameX.Launcher.dll \ --ServerId=1000 \ --ServerType=Game \ --IsEnableTcp=true \ --InnerPort=29100 \ --MetricsPort=29090 \ --IsEnableHttp=true \ --HttpPort=28080 \ --IsEnableWebSocket=true \ --WsPort=29110 \ --HttpIsDevelopment=true \ --MinModuleId=10 \ --MaxModuleId=9999 \ --TagName=GameFrameX \ --DatabaseProvider=Sqlite \ --DataBaseUrl="Data Source=data/gameframex.db"
- Open
Server.slnx; if your Rider version does not support.slnx, openServer.sln. - Start MongoDB:
docker compose up -d mongodb. - Create or edit a
.NET Projectrun configuration forGameFrameX.Launcher. - Set
Working directoryto$SolutionDir$/bin/app_debug. - Leave
Program argumentsempty. - Click Debug. If
bin/app_debugdoes not exist yet, rundotnet build Server.slnonce.
- Open
Server.slnx; if your Visual Studio version does not support.slnx, openServer.sln. - Set
GameFrameX.Launcheras the startup project. - Start MongoDB:
docker compose up -d mongodb. - Set
Working directorytobin\app_debug. - Leave
Command line argumentsempty. - Press F5. If the output directory does not exist yet, run Build Solution once.
dotnet GameFrameX.Launcher.dll \
--ServerId=1000 \
--ServerType=Game \
--IsEnableTcp=true \
--InnerPort=29100 \
--MetricsPort=29090 \
--IsEnableHttp=true \
--HttpPort=28080 \
--IsEnableWebSocket=true \
--WsPort=29110 \
--HttpIsDevelopment=true \
--MinModuleId=10 \
--MaxModuleId=9999 \
--TagName=GameFrameX \
--DatabaseProvider=Sqlite \
--DataBaseUrl="Data Source=data/gameframex.db"| Endpoint | URL | Description |
|---|---|---|
| Health Check | http://localhost:29090/health |
Service health status |
| Metrics | http://localhost:29090/metrics |
Prometheus metrics |
| Test API | http://localhost:28080/game/api/test |
HTTP connectivity test |
| Online Admin API | http://localhost:28090/online/admin/{action} |
Online capability admin plane (enabled by default in Configs/app_config.json via Online.EnableAdminApi) |
Security note: the Online admin API currently has no authentication and listens on all network interfaces (
0.0.0.0, port fromOnlineAdminPort). Keep it on trusted internal networks only — protect it with a firewall / security group, or setOnline.EnableAdminApitofalsebefore exposing the server to an untrusted network.
Server_main/
├── GameFrameX.Launcher/ # Application entry point (Executable)
│ ├── Program.cs # Bootstrap: register state types & protocol messages
│ └── StartUp/
│ └── AppStartUpGame.cs # Game server startup flow
│
├── GameFrameX.Hotfix/ # Hot-update layer (Business logic, runtime-replaceable)
│ ├── Logic/
│ │ ├── Http/ # HTTP request handlers
│ │ │ ├── TestHttpHandler.cs
│ │ │ ├── ReloadHttpHandler.cs
│ │ │ ├── Player/ # Account login, online queries
│ │ │ └── Bag/ # Item sending
│ │ ├── Player/
│ │ │ ├── Bag/ # Bag component agent
│ │ │ ├── Login/ # Login/logout logic
│ │ │ └── Pet/ # Pet component agent
│ │ ├── Account/ # Account component agent
│ │ └── Server/ # Server global component agent
│ └── StartUp/ # Hot-update startup flow
│ ├── AppStartUpHotfixGameByEntry.cs # Entry point
│ ├── AppStartUpHotfixGameByMain.cs # Network/connection management
│ ├── AppStartUpHotfixGameByHeart.cs # Heartbeat handling
│ └── AppStartUpHotfixGameByGateWay.cs # Gateway communication
│
├── GameFrameX.Apps/ # Application state layer (Non-hot-updatable)
│ ├── ActorType.cs # Actor type enum definition
│ ├── Account/Login/ # Login state + component
│ ├── Player/
│ │ ├── Bag/ # Bag state + component
│ │ ├── Player/ # Player state + component
│ │ └── Pet/ # Pet state + component
│ ├── Server/ # Server global state + component
│ └── Common/
│ ├── Session/ # Session management (SessionManager)
│ ├── Event/ # Event ID definitions
│ └── EventData/ # Event arguments
│
├── GameFrameX.Config/ # Config table system (Luban generated)
│ ├── ConfigComponent.cs # Config loading singleton
│ ├── Tables/ # Generated config table classes
│ ├── TablesItem/ # Config data models
│ └── json/ # JSON config data files
│
├── GameFrameX.Proto/ # Network protocol definitions
│ ├── Basic_10.cs # Basic protocols (heartbeat, etc.)
│ ├── Bag_100.cs # Bag protocols
│ ├── User_300.cs # User/account protocols
│ └── BuiltIn/ # Built-in system protocols
│
├── GameFrameX.Architecture.Analyzers/ # Compile-time architecture rules
│
├── Server.slnx # Recommended solution for newer IDEs
├── Server.sln # Fallback solution for IDEs that do not support .slnx
├── Dockerfile # Docker multi-stage build
├── docker-compose.yml # Docker Compose orchestration
└── LICENSE.md # Apache License 2.0
GameFrameX uses a three-layer separation pattern that enables hot-updating business logic without server downtime.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ State │────▶│ Component │◀────│ ComponentAgent│
│ (Data Def) │ │ (Shell) │ │ (Logic) │
│ Apps Layer │ │ Apps Layer │ │ Hotfix Layer │
│ Not Hot-fix │ │ Not Hot-fix │ │ Hot-fixable │
└──────────────┘ └──────────────┘ └──────────────┘
Inherit CacheState to define persistent data structures. The framework handles MongoDB serialization automatically.
// GameFrameX.Apps/Player/Bag/Entity/BagState.cs public sealed class BagState : CacheState { public Dictionary<int, BagItemState> List { get; set; } = new(); } public sealed class BagItemState { public long ItemId { get; set; } public long Count { get; set; } }
Inherit StateComponent<TState> to serve as the bridge between state and logic.
// GameFrameX.Apps/Player/Bag/Component/BagComponent.cs [ComponentType(GlobalConst.ActorTypePlayer)] public class BagComponent : StateComponent<BagState> { }
Inherit StateComponentAgent<TComponent, TState> to write hot-updatable business code.
// GameFrameX.Hotfix/Logic/Player/Bag/BagComponentAgent.cs public class BagComponentAgent : StateComponentAgent<BagComponent, BagState> { public async Task OnAddBagItem(INetWorkChannel netWorkChannel, ReqAddItem message, RespAddItem response) { // Validate item config exists foreach (var item in message.ItemDic) { if (!ConfigComponent.Instance.GetConfig<TbItemConfig>() .TryGet(item.Key, out var _)) { response.ErrorCode = (int)OperationStatusCode.NotFound; return; } } await UpdateChanged(netWorkChannel, message.ItemDic); } public async Task<BagState> UpdateChanged(INetWorkChannel netWorkChannel, Dictionary<int, long> itemDic) { var bagState = OwnerComponent.State; var notify = new NotifyBagInfoChanged(); foreach (var item in itemDic) { if (bagState.List.TryGetValue(item.Key, out var value)) { value.Count += item.Value; } else { bagState.List[item.Key] = new BagItemState { Count = item.Value, ItemId = item.Key }; } } await netWorkChannel.WriteAsync(notify); await OwnerComponent.WriteStateAsync(); // Auto-persist to MongoDB return bagState; } }
Inherit BaseHttpHandler and register with [HttpMessageMapping].
// GameFrameX.Hotfix/Logic/Http/TestHttpHandler.cs [HttpMessageMapping(typeof(TestHttpHandler))] [HttpMessageResponse(typeof(HttpTestResponse))] [Description("Test API endpoint")] public sealed class TestHttpHandler : BaseHttpHandler { public override Task<string> Action(string ip, string url, Dictionary<string, object> parameters) { var response = new HttpTestResponse { Message = "hello" }; return Task.FromResult(HttpJsonResult.SuccessString(response)); } }
The framework provides two RPC handler base classes with automatic ComponentAgent injection:
// Player-level message (bound to a specific player Actor) [MessageMapping(typeof(ReqAddItem))] internal sealed class AddItemHandler : PlayerRpcComponentHandler<BagComponentAgent, ReqAddItem, RespAddItem> { protected override async Task ActionAsync(ReqAddItem request, RespAddItem response) { await ComponentAgent.OnAddBagItem(NetWorkChannel, request, response); } } // Global-level message (bound to the server Actor) [MessageMapping(typeof(ReqHeartBeat))] internal sealed class HeartBeatHandler : GlobalRpcComponentHandler<ServerComponentAgent, ReqHeartBeat, RespHeartBeat> { protected override Task ActionAsync(ReqHeartBeat request, RespHeartBeat response) { return Task.CompletedTask; } }
Use the [Event] attribute to bind the event argument type. The framework automatically dispatches to the corresponding ComponentAgent.
[Event(typeof(OnRoleOnlineEventArgs))] internal sealed class PlayerOnlineEventListener : EventListener<PlayerComponentAgent> { protected override Task HandleEventAsync(PlayerComponentAgent agent, GameEventArgs gameEventArgs) { return Task.CompletedTask; } }
The Roslyn source generator automatically handles Actor message queue scheduling. Control invocation behavior through attributes:
| Attribute | Description | Use Case |
|---|---|---|
[Service] |
Default mode; method calls are enqueued to the Actor message queue | All business methods |
[ThreadSafe] |
Skip message queue, invoke directly (requires thread-safe implementation) | Read-only operations, stateless computation |
[Discard] |
Fire-and-forget, do not await the return value | Logging, statistics where results are not needed |
[TimeOut(ms)] |
Set timeout for message queue invocation | Long operations requiring timeout control |
public class ServerComponentAgent : StateComponentAgent<ServerComponent, ServerState> { // Enqueued to Actor message queue [Service] public virtual Task<bool> IsOnline(long roleId) { ... } // Skip message queue, thread-safe direct call [Service] [ThreadSafe] public virtual long FirstStartTime() { return State.FirstStartTime; } // Fire-and-forget, non-blocking [Service] [Discard] public virtual ValueTask AddOnlineRole(long roleId) { OwnerComponent.OnlineSet.Add(roleId); return ValueTask.CompletedTask; } }
Use the ConfigComponent singleton to access Luban-generated config tables:
var config = ConfigComponent.Instance.GetConfig<TbItemConfig>(); // Safe query with TryGet if (config.TryGet(itemId, out var itemConfig)) { // Use itemConfig.Name, itemConfig.Type, etc. }
Use the GameDb static class for MongoDB CRUD operations:
// Query var state = await GameDb.FindAsync<LoginState>( m => m.UserName == userName && m.Password == password); // Add or update await GameDb.AddOrUpdateAsync(loginState); // List query var list = await GameDb.FindListAsync<LoginState>(m => m.Id != 0); // Delete var count = await GameDb.DeleteAsync(state);
The hot-update system allows replacing business logic without stopping the server.
- Apps Layer (
GameFrameX.Apps): Contains state definitions and component shells — not hot-updatable - Hotfix Layer (
GameFrameX.Hotfix): Contains all business logic — hot-updatable - Hotfix assembly outputs to the
hotfix/directory, loaded at runtime byHotfixManager
# Trigger via HTTP endpoint (with version number) curl "http://localhost:28080/game/api/Reload?version=1.0.1"
GameFrameX.Architecture.Analyzers is a Roslyn analyzer project that enforces the Apps/Hotfix architecture at compile time. It is referenced as an analyzer by GameFrameX.Apps, GameFrameX.Hotfix, and GameFrameX.Launcher only; GameFrameX.Config, GameFrameX.Proto, and test assemblies are ignored by design.
| ID | Rule |
|---|---|
GFX0001 |
BaseCacheState subclasses must be defined in GameFrameX.Apps. |
GFX0002 |
StateComponent<TState> subclasses must be defined in GameFrameX.Apps. |
GFX0003 |
BaseHttpHandler subclasses must be defined in GameFrameX.Hotfix. |
GFX0004 |
IHotfixBridge implementations must be defined in GameFrameX.Hotfix. |
GFX0005 |
IComponentAgent implementations must be defined in GameFrameX.Hotfix. |
GFX0006 |
[MessageMapping] handlers must be defined in GameFrameX.Hotfix. |
GFX0007 |
[MessageRpcMapping] handlers must be defined in GameFrameX.Hotfix. |
GFX0008 |
IEventListener implementations must be defined in GameFrameX.Hotfix. |
GFX0009 |
ITimerHandler implementations must be defined in GameFrameX.Hotfix. |
GFX0010 |
[MessageMapping] handlers must be sealed. |
GFX0011 |
IEventListener implementations must be sealed. |
GFX0012 |
[MessageMapping] handler type names must end with Handler. |
GFX0013 |
IEventListener implementation type names must end with EventListener. |
GFX0014 |
IComponentAgent implementation type names must end with ComponentAgent. |
GameFrameX consists of the repositories below: the build-time toolchain generates protocol and config code, while game clients, game servers and the operations backend cooperate at runtime.
%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 30, "rankSpacing": 50}}}%%
flowchart TB
subgraph Toolchain["Build-time toolchain"]
direction TB
Luban["luban<br/>Luban fork"] -- "Luban.dll · daily sync" --> Config["Config<br/>Excel tables"]
Tools["Tools<br/>ProtoExport"] -- "ProtoExport.dll · weekly sync" --> Protobuf["Protobuf<br/>proto3 definitions"]
FairyGUI["FairyGUIProject<br/>UI source"]
end
subgraph Runtime["Runtime"]
direction TB
subgraph Clients["Game clients"]
direction TB
Unity["Unity<br/>Unity 2019.4.40+ · C#"]
Godot["Godot<br/>Godot 4.7 · C#"]
Cocos["CocosCreator<br/>Cocos 3.8 · TS"]
Laya["LayaBox<br/>LayaAir · TS"]
end
subgraph Backend["Backend"]
direction TB
Admin["Admin<br/>Admin · Client · Hub API"]
subgraph GameServers["Game servers"]
direction TB
Server["Server<br/>official game repo (this repo)"]
ServerSource["Server.Source<br/>framework repo (NuGet)"]
end
end
end
subgraph Infrastructure["Infrastructure"]
direction TB
subgraph Storage["Storage"]
direction TB
Mongo[("MongoDB<br/>game servers")]
Postgres[("PostgreSQL<br/>Admin")]
end
subgraph Libraries["Base libraries · NuGet"]
direction TB
Foundation["Foundation<br/>.NET base libraries"]
SuperSocket["SuperSocket<br/>socket framework"]
end
end
Toolchain -- "generated code · config data · UI packages" --> Runtime
Clients -- "TCP / WebSocket / HTTP" --> Backend
Admin -- "HTTP management API" --> GameServers
Runtime -- "data storage · NuGet packages" --> Infrastructure
| Project | Role | Tech Stack | Integration |
|---|---|---|---|
| Unity | Unity client project: assembles 90+ framework packages from the GameFrameX UPM registry, HybridCLR hot update, login / bag / room samples | Unity 2019.4.40+, HybridCLR, YooAsset, FairyGUI, UniTask | Consumes Protobuf / Config / FairyGUIProject output; TCP 29100 + HTTP 28080 to Server, HTTP 20808 to Admin Client API |
| Server (this repo) | Official game repo / user starting template: consumes GameFrameX 2.0 NuGet packages; ConnectFour bridged onto the Online capabilities demos the shortest loop (boot → matchmaking → match → settlement → leaderboard) | .NET 10, MongoDB, Docker | Listens on TCP 29100 / WebSocket 29110 / HTTP 28080; drives the framework repo backlog via issues and sample requests |
| Admin | Multi-tenant operations backend: Admin (20802) / Client (20808) / Hub (20806) hosts + Vue console, covering game areas, announcements, mail, orders & payment, remote config, LiveOps | .NET 10, SqlSugar, PostgreSQL, Vue 3.5, PrimeVue | Calls Server through each game area's HttpManageUrl; Client API serves global info, login and payment callbacks to game clients |
| luban | GameFrameX fork of Luban: merged upstream v5.1.0, adds the gameframex table importer and cs-dotnet-json / cs-dotnet-bin code targets |
.NET 10, Scriban | Publishes Luban tar.gz and Docker image; synced daily into Config Tools/ |
| Config | Config table repository: Excel data tables + schema + localization tables, one-click scripts generate client and server code and data | Excel, Luban | gen-client-* → Unity; gen-server-json → Server; gen-server-bin → Server.Source; gen-godot-json / gen-cocos-json / gen-laya-json → Godot / CocosCreator / LayaBox |
| Protobuf | Unified network protocol definitions: proto3, messages and error codes grouped by the numeric module ID in each file name (positive = client↔server, negative = server-internal) | proto3 | Proto2CsExport_Server → Server; Proto2CsExport_Client → Unity; Proto2CsExport_Godot / Proto2TsExport_CocosCreator / Proto2TsExport_LayaBox → other clients; CI publishes a six-language Release on every push |
| Tools | ProtoExport protocol code generator: C# / TypeScript / C++ / Lua / Go, available as CLI, Avalonia GUI and Docker image | .NET 10, Avalonia 12 | ProtoExport.dll synced weekly into Protobuf Tools/; Docker image gameframex/gameframex-tools |
| Project | Role | Tech Stack | Integration |
|---|---|---|---|
| Foundation | Modular .NET libraries: localization, JSON, command-line options, logging, HTTP, encryption, hashing, ORM base entities, idempotency | .NET | NuGet packages referenced by Server, Server.Source, Admin, Tools |
| SuperSocket | GameFrameX fork of SuperSocket: .NET 10 targets, dependency injection, KCP / ReliableSession for weak-network game traffic | .NET 10 | NuGet: Server (ClientEngine), Server.Source (Server / Kcp / Udp / WebSocket) |
| Server.Source | Framework repo (the GameFrameX distribution itself): L0–L5 monotonic framework source + the Online capability family; produces the 2.0 NuGet packages | .NET 10, MongoDB, Docker | 2.0 NuGet packages consumed by this repo (Server); receives Config gen-server-bin output; multi-process deployment |
| Godot | Godot .NET client with reusable runtime modules, editor plugins and hot-update assemblies | Godot 4.7, C# | Config gen-godot-json, Protobuf Proto2CsExport_Godot; TCP 29100 / WebSocket 29110 to Server |
| CocosCreator | Cocos Creator client, migrated from the Unity version | Cocos Creator 3.8, TypeScript | npm run gen:proto / gen:config call Protobuf / Config scripts; WebSocket to Server |
| LayaBox | LayaBox client | LayaAir, TypeScript | Config gen-laya-json, Protobuf Proto2TsExport_LayaBox; WebSocket to Server |
| FairyGUIProject | FairyGUI editor project: design source of all game UI | FairyGUI Editor | Publishes UI packages to Unity Assets/Bundles/UI and code to Assets/Hotfix/UI/FairyGUI/ |
| Parameter | Description | Default | Example |
|---|---|---|---|
ServerType |
Server type | — | Game |
ServerId |
Unique server ID | — | 1000 |
IsEnableTcp |
Enable TCP service | false |
true |
InnerPort |
TCP internal port | — | 29100 |
IsEnableHttp |
Enable HTTP service | false |
true |
HttpPort |
HTTP service port | 0 |
28080 |
IsEnableWebSocket |
Enable WebSocket service | false |
true |
WsPort |
WebSocket service port | 0 |
29110 |
MetricsPort |
Prometheus metrics port | 0 |
29090 |
HttpIsDevelopment |
Enable HTTP development mode | false |
true |
MinModuleId |
Minimum module ID handled by the game server | — | 10 |
MaxModuleId |
Maximum module ID handled by the game server | — | 9999 |
TagName |
Runtime tag name | — | GameFrameX |
DataBaseUrl |
MongoDB connection string | — | mongodb://localhost:27017 |
DataBaseName |
Database name | — | gameframex |
[!NOTE] Local debugging can use the defaults in
GameFrameX.Launcher/StartUp/AppStartUpGame.cswithout passing arguments. The table above lists common override parameters. For the complete configuration reference (network, logging, actor, monitoring, security, etc.), see Configuration Management — GameFrameX.Server.Source.
dotnet GameFrameX.Launcher.dll \
--ServerId=1000 \
--ServerType=Game \
--IsEnableTcp=true \
--InnerPort=29100 \
--MetricsPort=29090 \
--IsEnableHttp=true \
--HttpPort=28080 \
--IsEnableWebSocket=true \
--WsPort=29110 \
--HttpIsDevelopment=true \
--MinModuleId=10 \
--MaxModuleId=9999 \
--TagName=GameFrameX \
--DatabaseProvider=Sqlite \
--DataBaseUrl="Data Source=data/gameframex.db"docker-compose up --build
| Port | Protocol | Description |
|---|---|---|
29090 |
HTTP | APM metrics / Health check |
29100 |
TCP | Game client connections |
29110 |
WebSocket | WebSocket connections |
28080 |
HTTP | HTTP API |
Message IDs are calculated by module ID shift: (moduleId << 16) + seqId
| Module | ID Range | File | Description |
|---|---|---|---|
| System | -10 ~ -1 | Player_-10.cs, Service_-3.cs |
Built-in system protocols |
| Basic | 10 | Basic_10.cs |
Heartbeat, server ready notification |
| Bag | 100 | Bag_100.cs |
Item CRUD, use, compose |
| User | 300 | User_300.cs |
Login, register, character list |
| Component | Technology |
|---|---|
| Runtime | .NET 10.0 |
| Database | MongoDB |
| Networking | SuperSocket |
| Serialization | protobuf-net |
| Config Generation | Luban |
| Code Generation | Roslyn Source Generator |
| Monitoring | OpenTelemetry + Prometheus |
| Object Mapping | Mapster |
| Containerization | Docker + Docker Compose |
- Fork this repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add some feature') - Push to the branch (
git push origin feature/amazing-feature) - Create a Pull Request
This project is licensed under the Apache License 2.0. See the LICENSE.md file for details.