Endariel — Vidcraft時代のMinecraftネットワーク分散基盤
VidcraftのMinecraftエコシステムの基盤SDK:11ヶ月で2,133コミット、`fr.endariel`下に150以上のJavaクラス。BungeeCordがまだ単なるTCPプロキシだった2016年に、型付きRedis Pub/SubバスとNMS直接アクセスを敷設しました。この幹が2019年にUnitaleへと再生します。
- Java 8
- Spigot 1.10.2 (unispigot-serverフォーク)
- BungeeCord
- Jedis 2.8
- Apache HttpClient
- Socket.io
- Redis Pub/Sub
- Netty
- NMSリバースエンジニアリング
- Maven マルチモジュール
- 分散システム
背景
2016年、フランスのMinecraftシーンはMineplexやHypixelを見ながら、独自のモノリシック・クラスタを組まずに数万人規模のマルチモードネットワークを運営する方法を模索していました。EndarielのスタジオであるVidcraftは、その土俵に立つことを望みました:複数のゲームモード、共有経済、サーバー間を移動してもアイデンティティを失わないプレイヤー体験。ピーク時にネットワークは累計10万人以上のユニークプレイヤーに到達し、相互接続された50台以上のSpigotインスタンスで同時接続1万以上を支えました。
問題は、Mojangがサーバーをこの用途で設計していなかったことです。プロトコル、エンジン、プレイヤー状態、すべてがシングルインスタンス前提。そして2016年のKubernetesはまだニッチで、Bukkit JVM上のこの種の負荷に対応する既製のオーケストレーターは存在しませんでした。分散基盤は自力で敷く必要がありました。
担当した役割
エコシステムを統括するSDK——各ゲームモードが接続するJavaの基盤——を設計し、実装しました。分散アーキテクチャ、公式Minecraftサーバーのリバースエンジニアリング、インスタンス間同期バス、BungeeCordとの統合、これらが私の所管範囲でした。
Vidcraftでの中心的なミッションは、まさにこれでした:ミニゲーム用の独自SDKを開発すること。fr.endarielの幹はこの枠組みのなかで生まれたのであって、後付けではありません — 2016年11月21日に初コミットされたLaserGameが、その上で動いた最初のミニゲームです。
構築したもの
SDK — fr.endariel namespace、11ヶ月で2,133コミット
SDKの最初のコミットは2016年7月14日:138ファイルが一度に登録され、同日のうちにプロジェクトはコードネーム「IceCube」から「Endariel」へ改名されています。11ヶ月後の2017年5月末時点で、Javaの幹は150以上のクラスを抱え、主に2つのツリーに分かれています。
fr.endariel.api.*は分散レイヤーをホストします:
- 11以上の型付きRedisサブスクライバーを、
SubJedisPubSubという抽象クラスから派生させました —CommunPubSub、SDKPubSub、ServerPlayersPubSub、PlayerEliminatedSubscriber、ServerStatusSubscriberなど。文字列の盲目的なブロードキャストではなく、各ドメインが専用の型付きサブスクリプションクラスを持ち、適切なハンドラへディスパッチします。 - 14以上のRESTクライアント:ある程度のレイテンシを許容できるインスタンス横断オペレーション用(Bag、Boost、Contact、Feature、Guild、Money、News、Player、Properties、Sanction、SearchPlayer、Session…)。
- ホットパス用の専用Redisクライアント:Feature、Modo、Party、Player、Sanction、Server、Settings。
fr.endariel.sdk.*はゲームプレイの中核を含みます:
- Players —
EndCraftPlayer、EndPlayer、PlayerInflator(RedisとRESTからのプレイヤーデータ遅延ロード)、PlayerContainer、SettingsHandler、EndCraftOfflinePlayer。 - Morphs —
MorphAPI、MorphManager、MorphPacketHandler、NettyManager:ProtocolLibに依存せず、低レベルのNettyアクセスでモーフィングパケットを注入。 - ソーシャル系・経済系機能:ギルド、パーティ、グループ、ガジェット、マウント、ペット、ルートボックス、インベントリバッグ、カスタムBossBar。
- Aura — 10種類前後の合成可能なビジュアルエフェクト:
AngelAura、CloudAura、DrinkAura、ExplosionsAura、HelicopterAura、HellAura、MultiColorRingAura、RainAura、ScannerAura、TailAura。 - 分散チャット —
ChatPubSubRedisによるインスタンス横断ブロードキャスト。 - カスタムAdvancement API — 1.10.2サーバー上で1.12+のセマンティクスを成立させる仕組み。
- バージョン別PVP — 1.8と1.10で別々のリスナー。ヒットボックスや戦闘パケットがバージョン間で変わるため。
2016–2017年のスタック
Mavenマルチモジュール、plexus-compiler-eclipseによるEclipseコンパイラ、Maven Shadeでのパッケージング。サーバー側はSpigot 1.10.2-R0.1-SNAPSHOTをフォークした自家製ビルドunispigot-serverを、git.endariel.fr上のプライベートNexusで配布。RedisへのアクセスはJedis 2.8.1 + Apache commons-pool2のコネクションプール。REST用にApache HttpClient 4.1.1。社内ツールへのリアルタイム配信にSocket.io 0.8.3(Javaクライアント)。シリアライゼーションはorg.json。Redissonなし、Hazelcastなし、ORMなし、MariaDB直接接続もなし:Redisファースト、それ以外はREST。2016年のBukkit JVM上で「合理的な」分散スタックの姿でした。
最初のミニゲーム
- LaserGame、初コミット2016年11月21日 — SDKから5ヶ月後、最初のミニゲームが世に出て、幹が機能することを証明します。
- Arena、2017年5月6日に始まった短命のプロトタイプ。
- GameSDK2、ゲームエンジンの書き直しを2017年5月29日に開始 — 2019年以降のUnitaleで生き延び成長するピースです。
最も難しかった点
2016年に、近代的なオーケストレーターなしでサーバー間リアルタイム状態同期を実現すること。 当時、MineplexやHypixelは独自ミドルウェアを持つモノリシック・クラスタで稼働しており、BungeeCordはルーティング以上のことをしないTCPプロキシでした。Endarielの賭けは、SDKの最初の行からドメイン別の専用クラスで型付けされたRedis Pub/Subディスパッチ(CommunPubSub、SDKPubSub、ServerPlayersPubSub…)を採用することでした。巨大なswitchでパースされる生の文字列ではなく、です。2016年では辛い設計選択です — シリアライゼーションを手書きし、スキーマバージョンを管理し、新しいチャネルごとにアノテーションする必要があります — しかし、これこそがサブ秒のプレイヤーホップ、整合性のある経済、インスタンス横断のアンチチートを可能にする土台でした。
もう一つの難所:ProtocolLibなしでのモーフとカスタムインベントリ。当時の多くのプラグインはパケット傍受をProtocolLibに委譲していました。これはホットパスでCPUを消費し、リリースサイクルが予測不能な外部プロジェクトへの重い依存を生みます。私は下の道を選びました:NMS CraftBukkitのリバースエンジニアリング、未文書化のエンティティとパケットのマッピング、そしてNettyManagerとMorphPacketHandlerによるNetty直接アクセス。より速く、より自律的で、1.8 / 1.10 / 1.12+のマルチバージョンと互換 — ReflectionManagerがターゲットバージョンに応じて正しい内部実装を再結線します。
成果
- Vidcraftネットワークの存続期間中、累計10万人以上のユニークプレイヤーにサービス提供。
- ピーク時同時接続1万以上、クライアント側に体感的な劣化なし。
- 型付きRedis Pub/Subバスを通じて、50台以上のSpigotインスタンスを一つの一貫したネットワークとして統括。
- 11ヶ月(2016年7月 → 2017年5月)で
fr.endarielnamespace下に2,133コミット、2018年以前のJava幹の94% — 分散基盤は素早く敷かれ、固く保たれました。
そして続編、これは秘密ではありません:Vidcraftが2017年末に閉鎖されたとき、このJavaの幹は死ななかった、引き継がれたのです。2019年以降、fr.endariel namespaceはfr.unitale、次いでfr.hycubeへと移行し、スタックは近代化されました — 過渡レイヤーにRedisson、共有キャッシュにHazelcast探索、2020年にJavaモノリスから分離されたSymfony 3.3バックエンド。この第二の人生はUnitaleの案件紹介で語られています。Endarielは、その幹のオリジナル版です。
この案件はまた、その後に続く一連の発射台でもあります:TyphoonMC(GoでフルスクラッチしたMinecraftサーバーエンジン、GitHub 90+スター)、Dofus Touch(数百万プレイヤーのスケール課題)、Authlete(日本の銀行向けOAuth/OIDC SaaS運用)、そして現在のConexia Tahiti(技術統括)。同じ職人技 — Pub/Sub、整合性キャッシュ、清潔なライフサイクル、レジリエンス — を、異なるスケールで適用しています。