# GameFrameX.Server **Repository Path**: gameframex/GameFrameX.Server ## Basic Information - **Project Name**: GameFrameX.Server - **Description**: High-performance game server framework built on C# .NET 10.0 with Actor Model architecture, hot-update support, multi-protocol networking (TCP/WebSocket/HTTP/KCP), MongoDB persistence, and OpenTelemetry monitoring. - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: https://gameframex.doc.alianblank.com - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 6 - **Created**: 2024-07-24 - **Last Updated**: 2026-07-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: 游戏, 娱乐, 游戏开发, 游戏服务器, 网络游戏 ## README
![GameFrameX Logo](https://download.alianblank.com/gameframex/gameframex_logo_320.png) # GameFrameX Server [![.NET](https://img.shields.io/badge/.NET-10.0-purple.svg)](https://dotnet.microsoft.com) [![License](https://img.shields.io/badge/license-Apache%202.0-orange.svg)](LICENSE.md) [![Documentation](https://img.shields.io/badge/docs-gameframex.doc.alianblank.com-brightgreen.svg)](https://gameframex.doc.alianblank.com) **All-in-One Solution for Indie Game Development · Empowering Indie Developers' Dreams** [📖 Documentation](https://gameframex.doc.alianblank.com) · [🚀 Quick Start](#quick-start) · [💬 QQ Group: 467608841](https://qm.qq.com/cgi-bin/qm/qr?k=sYFd1nv6m2KZIWFLorZ5pBR0AE5ZhbuL&jump_from=webapi&authKey=oCu+uoL3n35fT5SEt7iLgGtROPxh31n/rHUxRlp0w1f+j38W4tKBuWyRH3KEdwHN) --- 🌐 **Language**: **English** | [简体中文](README.zh-CN.md) | [繁體中文](README.zh-TW.md) | [日本語](README.ja.md) | [한국어](README.ko.md) ---
## Project Overview GameFrameX Server is a high-performance game server framework built on C# .NET 10.0, featuring an **Actor Model** architecture with **hot-update** support. The framework enforces strict separation between persistent state and business logic, designed specifically for multiplayer online game scenarios. > Design Philosophy: Simplicity over complexity ## Core Features - **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 ## Architecture ``` ┌──────────────────────────────────────────────────────────────┐ │ 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 │ │ │ └──────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────┘ ``` ## Quick Start ### Prerequisites | Dependency | Version | | :--- | :--- | | [.NET SDK](https://dotnet.microsoft.com/download) | 10.0+ | | [MongoDB](https://www.mongodb.com/try/download/community) | 4.x+ | | IDE | Visual Studio 2022 / JetBrains Rider / VS Code | ### Installation & Run ```bash # 1. Clone the repository git clone https://github.com/GameFrameX/Server_main.git cd Server_main # 2. Restore dependencies dotnet restore # 3. Build dotnet build # 4. Run the game server dotnet run --project GameFrameX.Launcher \ --ServerType=Game \ --ServerId=1000 \ --APMPort=29090 ``` ### Verify Deployment | 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 | ## Project Structure ``` 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.sln # Visual Studio solution ├── Server.slnx # XML solution ├── Dockerfile # Docker multi-stage build ├── docker-compose.yml # Docker Compose orchestration └── LICENSE.md # Apache License 2.0 ``` ## Usage Examples ### Core Pattern: State - Component - Agent 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 │ └──────────────┘ └──────────────┘ └──────────────┘ ``` #### Step 1: Define State (Apps Layer) Inherit `CacheState` to define persistent data structures. The framework handles MongoDB serialization automatically. ```csharp // GameFrameX.Apps/Player/Bag/Entity/BagState.cs public sealed class BagState : CacheState { public Dictionary List { get; set; } = new(); } public sealed class BagItemState { public long ItemId { get; set; } public long Count { get; set; } } ``` #### Step 2: Create Component (Apps Layer) Inherit `StateComponent` to serve as the bridge between state and logic. ```csharp // GameFrameX.Apps/Player/Bag/Component/BagComponent.cs [ComponentType(GlobalConst.ActorTypePlayer)] public class BagComponent : StateComponent { } ``` #### Step 3: Implement Business Logic (Hotfix Layer) Inherit `StateComponentAgent` to write hot-updatable business code. ```csharp // GameFrameX.Hotfix/Logic/Player/Bag/BagComponentAgent.cs public class BagComponentAgent : StateComponentAgent { public async Task OnAddBagItem(INetWorkChannel netWorkChannel, ReqAddItem message, RespAddItem response) { // Validate item config exists foreach (var item in message.ItemDic) { if (!ConfigComponent.Instance.GetConfig() .TryGet(item.Key, out var _)) { response.ErrorCode = (int)OperationStatusCode.NotFound; return; } } await UpdateChanged(netWorkChannel, message.ItemDic); } public async Task UpdateChanged(INetWorkChannel netWorkChannel, Dictionary 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; } } ``` ### HTTP Handler Inherit `BaseHttpHandler` and register with `[HttpMessageMapping]`. ```csharp // GameFrameX.Hotfix/Logic/Http/TestHttpHandler.cs [HttpMessageMapping(typeof(TestHttpHandler))] [HttpMessageResponse(typeof(HttpTestResponse))] [Description("Test API endpoint")] public sealed class TestHttpHandler : BaseHttpHandler { public override Task Action(string ip, string url, Dictionary parameters) { var response = new HttpTestResponse { Message = "hello" }; return Task.FromResult(HttpJsonResult.SuccessString(response)); } } ``` ### RPC Message Handler The framework provides two RPC handler base classes with automatic ComponentAgent injection: ```csharp // Player-level message (bound to a specific player Actor) [MessageMapping(typeof(ReqAddItem))] internal sealed class AddItemHandler : PlayerRpcComponentHandler { 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 { protected override Task ActionAsync(ReqHeartBeat request, RespHeartBeat response) { return Task.CompletedTask; } } ``` ### Event Handling Use the `[Event]` attribute to bind event IDs. The framework automatically dispatches to the corresponding ComponentAgent. ```csharp [Event(EventId.PlayerLogin)] internal sealed class PlayerLoginEventHandler : EventListener { protected override Task HandleEvent(PlayerComponentAgent agent, GameEventArgs args) { return agent.OnLogin(); } } ``` ### Agent Method Attributes 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 | ```csharp public class ServerComponentAgent : StateComponentAgent { // Enqueued to Actor message queue [Service] public virtual Task 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; } } ``` ### Config Table Access Use the `ConfigComponent` singleton to access Luban-generated config tables: ```csharp var config = ConfigComponent.Instance.GetConfig(); // Safe query with TryGet if (config.TryGet(itemId, out var itemConfig)) { // Use itemConfig.Name, itemConfig.Type, etc. } ``` ### Database Operations Use the `GameDb` static class for MongoDB CRUD operations: ```csharp // Query var state = await GameDb.FindAsync( m => m.UserName == userName && m.Password == password); // Add or update await GameDb.AddOrUpdateAsync(loginState); // List query var list = await GameDb.FindListAsync(m => m.Id != 0); // Delete var count = await GameDb.DeleteAsync(state); ``` ### Hot Update Mechanism 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 by `HotfixManager` ```bash # Trigger via HTTP endpoint (with version number) curl "http://localhost:28080/game/api/Reload?version=1.0.1" ``` ### Architecture Analyzers `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` 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`. | ## Documentation & Resources ### Configuration | Parameter | Description | Default | Example | | :--- | :--- | :--- | :--- | | `ServerType` | Server type | — | `Game` | | `ServerId` | Unique server ID | — | `1000` | | `InnerPort` | TCP internal port | — | `29100` | | `HttpPort` | HTTP service port | `0` | `28080` | | `WsPort` | WebSocket service port | `0` | `29110` | | `MetricsPort` | Prometheus metrics port | `0` | `29090` | | `DataBaseUrl` | MongoDB connection string | — | `mongodb://localhost:27017` | | `DataBaseName` | Database name | — | `gameframex` | > **[!NOTE]** > The table above lists only the minimum startup parameters. For the complete configuration reference (network, logging, actor, monitoring, security, etc.), see **[Configuration Management — GameFrameX.Server.Source](https://github.com/GameFrameX/GameFrameX.Server.Source#configuration-management)**. ```bash dotnet GameFrameX.Launcher.dll \ --ServerType=Game \ --ServerId=1000 \ --InnerPort=29100 \ --HttpPort=28080 \ --WsPort=29110 \ --MetricsPort=29090 \ --DataBaseUrl=mongodb://127.0.0.1:27017 \ --DataBaseName=game_db ``` ### Docker Deployment ```bash 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 Protocol 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 | ### Tech Stack | 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 | ## Community & Support - [Official Documentation](https://gameframex.doc.alianblank.com) - [GitHub Organization](https://github.com/GameFrameX) - [Gitee Mirror](https://gitee.com/GameFrameX) - [Issue Tracker](https://github.com/GameFrameX/GameFrameX/issues) - [Discussions](https://github.com/GameFrameX/GameFrameX/discussions) ### Contributing 1. Fork this repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'feat: add some feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Create a Pull Request ## License This project is licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). See the [LICENSE.md](LICENSE.md) file for details.