logo
0
0
WeChat Login
style(readme): 应用标准头部模板,添加居中布局和导航链接

GameFrameX Logo

GameFrameX Server

Version .NET License Documentation

高性能・クロスプラットフォームのゲームサーバーフレームワーク

📖 ドキュメント🚀 クイックスタート💬 QQグループ: 467608841


🌐 言語: English | 简体中文 | 繁體中文 | 日本語 | 한국어


目次


プロジェクト概要

GameFrameX Server は、C# .NET 10.0 で開発された高性能・クロスプラットフォームのゲームサーバーフレームワークです。Actor モデルを採用し、ホットアップデート機構をサポートしています。マルチプレイヤーオンラインゲーム開発向けに設計されており、Unity3D、Godot、LayaBox など多様なクライアントプラットフォームとの統合をサポートします。

設計理念: 大道至簡、シンプルイズベスト

コア機能

高性能アーキテクチャ

  • Actor モデル: TPL DataFlow 上に構築されたロックフリー・高同時実行システム。メッセージパッシングにより従来のロックのパフォーマンス劣化を回避
  • 完全非同期プログラミング: 完全な async/await 非同期プログラミングモデル
  • ゼロロック設計: Actor 内部状態はメッセージキューによる直列化アクセスでロック不要
  • バッチ永続化: バッチDB書き込みをサポート。バッチサイズとタイムアウト設定可能
  • スノーフレーク ID 生成: 分散ユニーク ID ジェネレーター内蔵。ワーカーノード・データセンター設定対応

ホットアップデートシステム

  • ゼロダウンタイム更新: 実行時に新しいロジックアセンブリをロード。サービス停止不要
  • 状態・ロジック分離: 永続化状態データ(Apps 層)とホットアップデート可能なビジネスロジック(Hotfix 層)を厳密に分離
  • グレースフル移行: 旧アセンブリは10分間の猶予期間を保持。進行中のリクエスト完了後にアンロード
  • バージョン管理: HTTP エンドポイント経由でバージョン番号を指定してロード可能

マルチプロトコルネットワーク通信

  • TCP: SuperSocket ベースの高性能 TCP サーバー。メインゲーム通信プロトコル
  • UDP: オプションの UDP プロトコルサポート
  • WebSocket: SuperSocket WebSocket ベースの双方向通信
  • HTTP/HTTPS: Kestrel ベースの HTTP サービス。Swagger ドキュメント、CORS、ヘルスチェック対応
  • KCP: KCP プロトコルベースの UDP 信頼性伝送(実験的)
  • クロスプロセスメッセージング: RemoteMessaging モジュール内蔵。サーキットブレーカー、リトライ戦略、コンシステントハッシングシャーディング対応

データベースと永続化

  • MongoDB プライマリDB: 完全な MongoDB 統合。ヘルスステートマシン対応(Healthy → Degraded → Unhealthy → Recovering)
  • 透過的永続化: StateComponent の自動シリアライズ/デシリアライズ。定期的バッチ ReplaceOne 操作で永続化
  • 接続プール管理: 設定可能な接続プールとリトライ戦略
  • OpenTelemetry 統合: データベース操作メトリクス(レイテンシ、リトライ回数、ヘルスステータス)

モニタリングとオブザーバビリティ

  • OpenTelemetry: 包括的なメトリクス(Metrics)、トレーシング(Tracing)、ロギング(Logging)
  • Prometheus: ネイティブメトリクスエクスポートエンドポイント
  • Grafana Loki: ログ集約出力対応
  • Serilog: 構造化ログ。コンソール、ファイル、Loki マルチ出力対応

システムアーキテクチャ

┌─────────────────────────────────────────────────────────────────┐
│                       クライアント層                              │
│         Unity3D / Godot / LayaBox / Cocos Creator               │
├─────────────────────────────────────────────────────────────────┤
│                      ネットワーク層                               │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐           │
│  │   TCP    │ │WebSocket │ │   HTTP   │ │   KCP    │           │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘           │
├─────────────────────────────────────────────────────────────────┤
│                    メッセージ処理層                                │
│  ┌────────────────┐ ┌────────────────┐ ┌────────────────┐      │
│  │TCP メッセージ   │ │  HTTP ハンドラ │ │クロスプロセス   │      │
│  │ハンドラ        │ │              │ │メッセージルータ │      │
│  └────────────────┘ └────────────────┘ └────────────────┘      │
├─────────────────────────────────────────────────────────────────┤
│                      Actor 層                                    │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐           │
│  │ プレイヤー│ │ サーバー │ │  アカウント│ │ グローバル│          │
│  │  Actor   │ │  Actor   │ │  Actor   │ │  Actor   │           │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘           │
├─────────────────────────────────────────────────────────────────┤
│            コンポーネント・エージェント層(ホットアップデート境界)   │
│  ┌─────────────────────┐  ┌─────────────────────────────┐      │
│  │  Apps 層 (非ホット更) │  │ Hotfix 層 (ホット更可能)     │      │
│  │ StateComponent<T>   │←→│ StateComponentAgent<T,TState>│      │
│  │ CacheState          │  │ ComponentAgent               │      │
│  └─────────────────────┘  └─────────────────────────────┘      │
├─────────────────────────────────────────────────────────────────┤
│                     データベース層                                │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                    MongoDB                               │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘

プロジェクト構成

Server/
├── GameFrameX.Launcher/              # アプリケーションエントリポイント
├── GameFrameX.StartUp/               # 起動オーケストレーションと初期化
├── GameFrameX.Core/                  # コアフレームワーク(Actor システム、コンポーネント、イベント、ホット更新管理)
├── GameFrameX.Apps/                  # 状態データ層(アカウント、プレイヤー、サーバーモジュール)— ホット更新不可
├── GameFrameX.Hotfix/                # ビジネスロジック層(HTTP、プレイヤー、サーバーハンドラ)— ホット更新可能
├── GameFrameX.Config/                # ゲーム設定テーブル(JSON 形式、LuBan 生成)
├── GameFrameX.Core.Config/           # コア設定管理
├── GameFrameX.Proto/                 # ProtoBuf プロトコル定義
├── GameFrameX.ProtoBuf.Net/          # ProtoBuf シリアライズ実装
├── GameFrameX.NetWork/               # ネットワークコア(メッセージオブジェクト、センダー、WebSocket)
├── GameFrameX.NetWork.Abstractions/  # ネットワークインターフェース(IMessage、IMessageHandler、メッセージマッピング)
├── GameFrameX.NetWork.HTTP/          # HTTP サーバー(Swagger、Kestrel、BaseHttpHandler)
├── GameFrameX.NetWork.Kcp/           # KCP プロトコルサポート(UDP ベースの信頼性伝送)
├── GameFrameX.NetWork.Message/       # メッセージパイプラインとコーデック
├── GameFrameX.NetWork.RemoteMessaging/ # クロスプロセスリモートメッセージ(サーキットブレーカー、リトライ、コンシステントハッシング)
├── GameFrameX.DataBase/              # データベース抽象レイヤー
├── GameFrameX.DataBase.Mongo/        # MongoDB 実装(ヘルスモニタリング、リトライ、バッチ操作)
├── GameFrameX.Localization/          # ローカライゼーションシステム(Keys.*.cs + .resx リソースファイル)
├── GameFrameX.Monitor/               # OpenTelemetry + Prometheus メトリクス統合
├── GameFrameX.Utility/               # ユーティリティ(ログ、圧縮、オブジェクトプール、Mapster、Harmony)
├── GameFrameX.Client/                # テストクライアント(TCP 接続)
├── GameFrameX.CodeGenerator/         # Roslyn ソースジェネレーター(ホット更新プロキシラッパークラス)
├── GameFrameX.AppHost/               # .NET Aspire アプリケーションホスト
├── GameFrameX.AppHost.ServiceDefaults/ # Aspire 共有デフォルト設定(OTel、サービスディスカバリ)
└── Tests/
    └── GameFrameX.Tests/             # xUnit テストスイート

クイックスタート

前提条件

インストール手順

  1. リポジトリをクローン

    git clone https://github.com/GameFrameX/GameFrameX.git
    cd GameFrameX/Server
    
  2. 依存関係を復元

    dotnet restore
    
  3. プロジェクトをビルド

    dotnet build
    
  4. MongoDB を起動

    # ローカルインストール
    mongod --dbpath /path/to/data
    
    # または Docker を使用
    docker run -d -p 27017:27017 --name mongo mongo:8.2
    
  5. サーバーを起動

    dotnet run --project GameFrameX.Launcher -- \
        --ServerType=Game \
        --ServerId=1000 \
        --OuterPort=29100 \
        --HttpPort=28080 \
        --DataBaseUrl=mongodb://127.0.0.1:27017 \
        --DataBaseName=gameframex
    
  6. 起動確認

    • ヘルスチェック: http://localhost:28080/game/api/health
    • コンソールログで起動成功を確認

設定管理

GameFrameX はコマンドライン引数(--Key=Value)で設定を行います。すべての設定項目は StartupOptions クラスで定義されています。

サーバー設定

設定項目説明デフォルト
ServerTypeサーバータイプ(必須)なしGameSocial
ServerIdサーバー一意 IDなし1000
ServerInstanceIdサーバーインスタンス ID(同タイプの異なるインスタンスを区別)01001
IsSingleModeシングルプロセスモードfalsetrue
MinModuleIdビジネスモジュール開始 ID(モジュールシャーディング)0100
MaxModuleIdビジネスモジュール終了 ID(モジュールシャーディング)01000
TimeZoneサーバータイムゾーンAsia/ShanghaiUTC
IsUseTimeZoneカスタムタイムゾーンを有効化falsetrue
Language言語設定なしzh-CN

ネットワーク設定

設定項目説明デフォルト
InnerHost内部通信用 IP(クラスタ間)0.0.0.00.0.0.0
InnerPort内部通信用ポート888829100
OuterHost外部通信用 IP(クライアント向け)0.0.0.00.0.0.0
OuterPort外部通信用ポートなし29100
IsEnableTcpTCP サービスを有効化truetrue
IsEnableUdpUDP サービスを有効化falsetrue
IsEnableWebSocketWebSocket を有効化falsetrue
WsPortWebSocket ポート888929300
IsEnableHttpHTTP サービスを有効化truetrue
HttpPortHTTP サービスポート808028080
HttpsPortHTTPS サービスポートなし443
HttpUrlAPI ルートパス/game/api//game/api/
HttpIsDevelopmentHTTP 開発モード(Swagger を有効化)falsetrue

データベース設定

設定項目説明デフォルト
DataBaseUrlMongoDB 接続文字列なしmongodb://localhost:27017
DataBaseNameデータベース名なしgameframex
DataBasePasswordデータベースパスワードなしyour_password

Actor 設定

設定項目説明デフォルト
ActorTimeOutActor タスク実行タイムアウト(ミリ秒)3000060000
ActorQueueTimeOutActor キュータイムアウト(ミリ秒)3000060000
ActorRecycleTimeActor アイドルリサイクル時間(分)1530
SaveDataIntervalデータ保存間隔(ミリ秒)3000060000
SaveDataBatchCountバッチ保存数5001000
SaveDataBatchTimeOutバッチ保存タイムアウト(ミリ秒)3000060000

ログ設定

設定項目説明デフォルト
IsDebugデバッグログマスタースイッチfalsetrue
LogIsConsoleコンソール出力truefalse
LogIsWriteToFileファイル出力truefalse
LogEventLevelログレベルDebugInformation
LogRollingIntervalログローリング間隔DayHour
LogIsFileSizeLimit単一ファイルサイズ制限truefalse
LogFileSizeLimitBytesファイルサイズ制限104857600 (100MB)52428800
LogRetainedFileCountLimit保持ファイル数3190
LogIsGrafanaLokiGrafana Loki 出力falsetrue
LogGrafanaLokiUrlGrafana Loki URLhttp://localhost:3100

モニタリング設定

設定項目説明デフォルト
IsOpenTelemetryOpenTelemetry を有効化falsetrue
IsOpenTelemetryMetricsメトリクス収集を有効化falsetrue
IsOpenTelemetryTracing分散トレーシングを有効化falsetrue
MetricsPortPrometheus メトリクスポート0(HTTP ポートを共用)9090
IsMonitorMessageTimeOutメッセージ処理タイムアウト監視falsetrue
MonitorMessageTimeOutSecondsタイムアウト閾値(秒)15

ID 生成設定

設定項目説明デフォルト
WorkerIdスノーフレーク ID ワーカーノード ID12
DataCenterIdスノーフレーク ID データセンター ID12

起動コマンド例

# 最小起動パラメータ
dotnet GameFrameX.Launcher.dll \
    --ServerType=Game \
    --ServerId=1000 \
    --DataBaseUrl=mongodb://127.0.0.1:27017 \
    --DataBaseName=game_db

# フル起動パラメータ
dotnet GameFrameX.Launcher.dll \
    --ServerType=Game \
    --ServerId=1000 \
    --ServerInstanceId=1 \
    --InnerHost=0.0.0.0 \
    --InnerPort=29100 \
    --OuterHost=0.0.0.0 \
    --OuterPort=29100 \
    --HttpPort=28080 \
    --IsEnableHttp=true \
    --HttpIsDevelopment=true \
    --IsEnableWebSocket=false \
    --DataBaseUrl=mongodb://127.0.0.1:27017 \
    --DataBaseName=gameframex \
    --IsDebug=true \
    --IsOpenTelemetry=true \
    --IsOpenTelemetryMetrics=true \
    --LogIsConsole=true \
    --LogIsWriteToFile=true

ビジネスロジック開発

コンポーネント・エージェントパターン

フレームワークのコア設計パターンは状態・ロジック分離です。永続化状態(Apps 層、ホット更新不可)とビジネスロジック(Hotfix 層、ホット更新可能)を厳密に分離します。

1. 状態の定義(Apps 層)

// GameFrameX.Apps/Player/BagState.cs
public class BagState : BaseCacheState
{
    public List<ItemData> Items { get; set; } = new List<ItemData>();
    public int MaxSlots { get; set; } = 50;
}

2. コンポーネントの作成(Apps 層)

// GameFrameX.Apps/Player/BagComponent.cs
public class BagComponent : StateComponent<BagState>
{
    protected override async Task OnInit()
    {
        await base.OnInit();
        // コンポーネント状態の初期化
    }
}

3. ビジネスロジックの実装(Hotfix 層)

// GameFrameX.Hotfix/Logic/Player/BagComponentAgent.cs
public class BagComponentAgent : StateComponentAgent<BagComponent, BagState>
{
    public async Task<bool> AddItem(int itemId, int count)
    {
        if (State.Items.Count >= State.MaxSlots)
        {
            return false;
        }

        var item = new ItemData { Id = itemId, Count = count };
        State.Items.Add(item);

        await Save();
        return true;
    }
}

4. コンポーネントエージェントへのアクセス

// ActorManager 経由でコンポーネントエージェントを取得
var bagAgent = await ActorManager.GetComponentAgent<BagComponentAgent>(playerId);
var result = await bagAgent.AddItem(1001, 10);

HTTP ハンドラ

HTTP ハンドラは BaseHttpHandler を継承し、[HttpMessageMapping] 属性でルートを登録します。

[HttpMessageMapping(typeof(GetPlayerInfoHandler))]
[Description("プレイヤー情報を取得")]
public sealed class GetPlayerInfoHandler : BaseHttpHandler
{
    public override async Task<MessageObject> Action(
        string ip, string url,
        Dictionary<string, object> parameters,
        MessageObject messageObject)
    {
        var request = (GetPlayerInfoRequest)messageObject;
        var response = new GetPlayerInfoResponse();

        var agent = await ActorManager.GetComponentAgent<PlayerComponentAgent>(request.PlayerId);
        if (agent == null)
        {
            response.ErrorCode = (int)ResultCode.PlayerNotFound;
            return response;
        }

        response.PlayerInfo = await agent.GetPlayerInfo();
        return response;
    }
}

TCP/RPC メッセージハンドラ

TCP メッセージハンドラは、クライアントから TCP 接続経由で送信されるゲームメッセージを処理します。

単方向メッセージハンドラ:

[MessageMapping(typeof(ReqChatMessage))]
internal sealed class ChatMessageHandler : PlayerComponentHandler<ChatComponentAgent, ReqChatMessage>
{
    protected override async Task ActionAsync(ReqChatMessage request)
    {
        await ComponentAgent.ProcessChatMessage(request);
    }
}

RPC ハンドラ(リクエスト・レスポンス):

[MessageMapping(typeof(ReqAddItem))]
internal sealed class AddItemHandler : PlayerRpcComponentHandler<BagComponentAgent, ReqAddItem, RespAddItem>
{
    protected override async Task ActionAsync(ReqAddItem request, RespAddItem response)
    {
        try
        {
            // ComponentAgent は基底クラスにより自動注入
            await ComponentAgent.AddItem(request, response);
        }
        catch (Exception e)
        {
            LogHelper.Fatal(e);
            response.ErrorCode = (int)OperationStatusCode.InternalServerError;
        }
    }
}

イベントハンドラ

イベントシステムは Actor 間の疎結合通信に使用します。

[Event(EventId.PlayerLogin)]
internal sealed class PlayerLoginEventHandler : EventListener<PlayerComponentAgent>
{
    protected override Task HandleEvent(PlayerComponentAgent agent, GameEventArgs gameEventArgs)
    {
        if (agent == null)
        {
            return Task.CompletedTask;
        }

        // プレイヤーログインイベントの処理
        return agent.OnLogin();
    }
}

ホットアップデート機構

アーキテクチャ原理

ホットアップデートシステムは AssemblyLoadContext(回収可能)により、アセンブリのランタイムロード・アンロードを実現します:

┌───────────────────────────────────────────────────────┐
│  Apps 層(ホット更新不可)                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │StateComponent│  │StateComponent│  │StateComponent│   │
│  │ 永続化状態    │  │ 永続化状態    │  │ 永続化状態    │   │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘   │
│         │                │                │           │
├─────────┼────────────────┼────────────────┼───────────┤
│         ▼                ▼                ▼           │
│  Hotfix 層(ホット更新可能)— AssemblyLoadContext       │
│  経由でロード                                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │ComponentAgent│  │ComponentAgent│  │ComponentAgent│   │
│  │ ビジネスロジック│  │ ビジネスロジック│  │ ビジネスロジック│   │
│  └─────────────┘  └─────────────┘  └─────────────┘   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │
│  │ Msg Handler  │  │ EventHandler│  │ HttpHandler  │   │
│  └─────────────┘  └─────────────┘  └─────────────┘   │
└───────────────────────────────────────────────────────┘

ホットアップデートフロー

  1. 新ロジックのコンパイル: 更新された GameFrameX.Hotfix.dll をビルド
  2. アセンブリのデプロイ: サーバーの指定ディレクトリにコピー
  3. リロードのトリガー: HTTP エンドポイント経由でホットアップデートリクエストを発行
  4. アセンブリロード: HotfixManager が回収可能な AssemblyLoadContext で新 DLL をロード
  5. タイプスキャン: HotfixModule が新アセンブリ内のエージェント、ハンドラ、イベントリスナーをスキャン
  6. エージェント切り替え: ActorManager.ClearAgent() がキャッシュされたエージェントインスタンスをクリア
  7. グレースフル移行: 旧アセンブリは10分間の猶予期間を保持。進行中のリクエスト完了後にアンロード

ホットアップデート API

# ホットアップデートのトリガー(バージョン指定)
curl -X POST "http://localhost:28080/game/api/Reload?version=1.7.2"

Docker デプロイ

単一インスタンスデプロイ

docker-compose.yml を使用して MongoDB + Game + Social の完全環境を起動:

# ビルドして起動
docker compose up -d --build

# 実行状態を確認
docker compose ps

# ログを確認
docker compose logs -f game social

# 停止
docker compose down

サービスポートマッピング:

サービスコンテナポートホストポート説明
MongoDB2701737017データベース
Game TCP2910039100ゲームサーバー
Game HTTP2808038080ゲームサーバー HTTP API
Social TCP2940039400ソーシャルサーバー
Social HTTP2808138081ソーシャルサーバー HTTP API

マルチインスタンスデプロイ

docker-compose.multi.yml を使用して 1 MongoDB + 2 Social + 10 Game のクラスタ環境を起動:

# ビルドして起動
docker compose -f docker-compose.multi.yml up -d --build

# 実行状態を確認
docker compose -f docker-compose.multi.yml ps

# 停止
docker compose -f docker-compose.multi.yml down

クラスタトポロジ:

コンポーネントインスタンス数説明
MongoDB1共有データベース
Social2ソーシャルサーバー(social-1, social-2)
Game10ゲームサーバー(game-1 ~ game-10)

全インスタンスは Aspire スタイルの環境変数でサービスディスカバリを行います:

environment:
  services__Social_2001__tcp__0: "tcp://social-1:29400"
  services__Social_2002__tcp__0: "tcp://social-2:29401"
  services__Game_1001__tcp__0: "tcp://game-1:29100"
  # ...

カスタムビルド

# イメージをビルド
docker build -t gameframex/server:custom .

# 実行
docker run -d \
    --name my-game-server \
    -p 29100:29100 \
    -p 28080:28080 \
    gameframex/server:custom \
    --ServerType=Game \
    --ServerId=2000 \
    --DataBaseUrl=mongodb://mongo-host:27017 \
    --DataBaseName=my_game

マルチプロセス・クロスプロセス連携

クロスプロセススモークテスト

# マルチインスタンス環境が起動していることを確認
docker compose -f docker-compose.multi.yml up -d --build

# クロスプロセススモークテストを実行
./scripts/multi/smoke-cross-process.sh

スクリプトの検証内容:

  • game-1social クロスプロセスコール
  • game-2social クロスプロセスコール
  • code=0 および FriendCount >= 1 を返却

ボットストレステスト

実際のクライアントをシミュレートして「ログイン → オンライン → 能動的切断 → 再接続ログイン」を繰り返し:

# デフォルトパラメータで実行
./scripts/multi/run-bots-rpc.sh

# カスタムパラメータ
BOT_COUNT=200 \
TCP_PORT=49100 \
LOGIN_URL=http://127.0.0.1:48080/game/api/ \
DISCONNECT_AFTER_LOGIN_SECONDS=20 \
RUN_SECONDS=300 \
./scripts/multi/run-bots-rpc.sh

オプション環境変数:

変数説明デフォルト
BOT_COUNTボット数
TCP_PORTTCP 接続ポート49100
LOGIN_URLログイン API URLhttp://127.0.0.1:48080/game/api/
DISCONNECT_AFTER_LOGIN_SECONDSログイン後切断遅延(秒)20
RUN_SECONDS総実行時間(秒)300

トラブルシューティングコマンド

# 全サービスのログを確認
docker compose -f docker-compose.multi.yml logs -f

# 特定サービスのログを確認
docker compose -f docker-compose.multi.yml logs -f game-1 game-2 social-1 social-2

# リビルドして起動(コード変更後)
docker compose -f docker-compose.multi.yml up -d --build

モニタリングとオブザーバビリティ

エンドポイント

エンドポイント説明
http://<host>:<HttpPort>/game/api/healthヘルスチェック
http://<host>:<MetricsPort>/metricsPrometheus メトリクス

メトリクスカテゴリ

  • データベース: 操作レイテンシ(db_operation_latency_ms)、リトライ回数(db_open_retry_total)、ヘルスステータス(db_health_status
  • ネットワーク: 接続数、メッセージスループット、バイト転送量
  • ビジネス: プレイヤーログイン数、アクティブセッション数
  • システム: GC パフォーマンス、スレッドプールステータス

テスト

テストの実行

# 全テストを実行
dotnet test

# 特定のテストプロジェクトを実行
dotnet test Tests/GameFrameX.Tests/GameFrameX.Tests.csproj

# 詳細出力で実行
dotnet test --logger "console;verbosity=detailed"

テストカバレッジ

テストプロジェクトは xUnit ベースで、以下のモジュールをカバーしています:

テストディレクトリ説明
Utility/数学/固定小数点テスト、圧縮、乱数、ID 生成、シングルトン
NetWork/Kcp/KCP パイプラインフィルター、セッション管理、サーバー統合テスト
DataBase/MongoDB 接続・クエリテスト
ProtoBuff/Protobuf シリアライズ・オブジェクトプールテスト
Localization/ローカライゼーションキー値解析テスト
RemoteMessaging/クロスプロセスメッセージングテスト
UnifiedMessaging/統合クロスプロセスメッセージングテスト
StartUp/HTTP サーバールート登録テスト

コントリビュート

あらゆる形態の貢献を歓迎します!以下の手順に従ってください:

  1. このリポジトリをフォーク
  2. フィーチャーブランチを作成(git checkout -b feature/amazing-feature
  3. 変更をコミット(git commit -m 'feat: 機能を追加'
  4. ブランチにプッシュ(git push origin feature/amazing-feature
  5. Pull Request を作成

コミットメッセージは Conventional Commits 仕様に従ってください。


ライセンス

本プロジェクトは MIT ライセンスApache License 2.0 のデュアルライセンスで配布されています。詳細は LICENSE ファイルを参照してください。


関連リンク


このプロジェクトが役に立ったら、Star をお願いします

Made by GameFrameX Team