# 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 Server
[](https://dotnet.microsoft.com)
[](LICENSE.md)
[](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.