OSS化します。何か質問があればコメントください。
- コードは完全リファクタリングしてMITかApacheかAGPLv3
- 画像は全て再作成してCC等に
- demoサイトはある程度形になったら用意
- Issue, PR, 画像生成等は歓迎
OSS化します。何か質問があればコメントください。
1月たったので現状レポート
本レポートは、レガシーCGIゲーム『@パーティⅡ』のモダンバックエンド再構築プロジェクト「party2re」について、開発開始から約1ヶ月時点の進行状況、アーキテクチャの多角的評価、および今後の課題とリスク分析をまとめたものです。
現在、プロジェクトは「Version 1.0 Reconstruction / Refactoring (Phase 5+)」の終盤に位置しており、バックエンドの基盤構築およびオリジナル仕様の再現(Parity対応)がほぼ完了しています。
APIおよび機能モジュールの完成: 39の機能モジュール(戦闘、経済、生産、ギルド、カジノ等のミニゲーム)が実装済みであり、OpenAPI 3.1に準拠した275パス / 297オペレーションのHTTP JSON APIが稼働しています。
レガシー仕様の完全再現(1:1 Parity): 初期開発においてAIエージェントが推測で実装した架空機能(オークション、配達クエスト、Eloレーティング制PvPなど)は、データベースマイグレーション(068番台以降)によって徹底的に削除・修正され、原作の素朴な仕様へと引き戻すリファクタリングが完了しています。
技術スタックの選定完了: Go言語によるモジュラーモノリスアーキテクチャを採用し、永続化層にMariaDB、一時状態(Transient State)の管理にValkey(Redis)を用いる構成が確立されています。
厳格な境界を持つモジュラーモノリス: internal/ 配下のパッケージがドメイン(battle, economy, guild, shopなど)ごとに明確に分離されています。マイクロサービスの複雑さを避けつつ、依存関係のスパゲッティ化を防ぐ現実的かつスケーラブルな設計です。
Valkeyへの状態オフロード: カジノのルーム状態、PvPのマッチング、パーティのロビーなど、短命で更新頻度の高い状態をRDBからValkeyへオフロードすることで、データベースの負荷を極小化する設計がなされています。
決定論的行ロック階層(Deterministic Row-Lock Hierarchy): MMORPG特有の複雑なトレードや戦闘処理において、データベースの行ロック取得順序に明確な階層(Rank 0〜8)が設けられています。
AST解析による自動検証: 上記のロック順序ルールが守られているかを、Goの抽象構文木(AST)を解析するLinter(lock_hierarchy_lint_test.go)によってCIで自動検証しています。これにより、ヒューマンエラーやAIの生成コードによるデッドロックの発生を未然に防ぐ堅牢な防御壁が構築されています。
.agents/rules/ ディレクトリに、マイグレーション制約、アーキテクチャ方針、セキュリティガイドラインなどを分割配置しています。LLMのコンテキストウィンドウを圧迫せず、タスクに必要なルールのみを選択的に読み込めるため、ハルシネーションを抑制しコード品質を安定させる高度な運用が行われています。現在オープンとなっているIssue情報から、プロジェクトは「APIサーバーの完成」から「フロントエンドとの結合および本番運用」へとフォーカスを移しています。
課題 1: APIからの表示ロジック・アセットの分離とテーマ対応
懸念: 現状のAPIレスポンスには、CGI時代の名残としてHTMLタグ(<b>など)や画像パス(bgimg/goods.gif)がハードコードされており、フロントエンド開発を阻害します。
現在のアプローチ (Issue #654): アセット生成を別プロジェクトへ切り離し、共通のJSONマニフェストを定義します。APIは抽象的な asset_id のみを返し、クライアント側でテーマ(クラシックスタイル、モダンスタイル等)に応じた画像を解決するアーキテクチャへのリファクタリングが計画されています。
課題 2: 無効なリクエストによるバックエンド負荷とUIロジックの重複
懸念: 死亡状態や疲労状態でのアクションなど、無効なリクエストがデータベースのトランザクションまで到達してしまいます。また、フロントエンド側で「今何ができるか」の判定ロジックを再実装すると、二重管理になります。
現在のアプローチ (Issue #629): Valkeyにキャラクターのステータス投影(Projection)を持たせ、超高速(<0.5ms)で「現在実行可能なアクション一覧(ホワイトリスト)」のみを返す Gateway API を構築します。UIはこのリストを描画するだけで済むようになります。
課題 3: UI非依存のゲームループ検証の欠如
懸念: ブラウザベースのE2Eテストは実行コストが高く、壊れやすい傾向があります。
現在のアプローチ (Issue #650, #646): Gateway APIを活用し、Goネイティブで動作する「ヘッドレス仮想プレイヤー(自律エージェント)」を構築します。これにより、ミリ秒単位での超高速なE2Eゲームプレイシミュレーションが可能になります。
課題 4: 本番インフラの堅牢性不足
懸念: アプリケーション起動時のDB接続保証や、外部公開時のセキュリティ設定が未成熟です。
現在のアプローチ (Issue #693, #691, #677): 起動時のMariaDB/Valkey接続必須化、CORSおよびIPベースのレートリミットの実装、プロセス内メモリ(グローバルマップ等)のValkeyへの移行によるステートレス化・水平スケール対応が進行中です。
提示されたロードマップやIssueの範囲外で、将来的に重大なブロッカーとなる可能性が高い課題を指摘します。
潜在リスク 1: 分散システムにおけるデータの不整合(MariaDBとValkey間)
潜在リスク 2: API化によるBOT・マクロの脅威とゲーム内経済の崩壊
潜在リスク 3: フロントエンドとバックエンドのステート同期(通信遅延時のUX)
潜在リスク 4: 認証フローとアカウントのリカバリ手法
今の作り方だと、おそらくこういうこともできる。
party2re の堅牢なJSON API(Issue #629)を活用し、公式のWeb GUI(React)とは別軸のクライアントとして、「Discord / Slack 統合型チャットクライアント」を開発する構想です。
単にゲームをチャットツールに移植するのではなく、TRPG(テーブルトークRPG)のように「全プレイヤーの行動ログが1つのチャンネルで共有される熱狂」と、「人間と自律型AIエージェントが同じチャンネルで会話し、共闘する体験」を創出します。
個人の画面内で完結するWeb UIとは異なり、行動の結果がすべてテキストとしてチャンネルにブロードキャストされます。
[ログ] @kau は宿屋に泊まり、HPが全回復した! [ログ] @kau はドラゴンに敗北した... など、他人のプレイ状況がタイムラインに流れ、自然なコミュニケーションや共闘のきっかけが生まれます。チャットクライアントであっても、プレイヤーに /attack のようなコマンドを手打ちさせることはしません。
API(GET /context)から返却される available_actions のリストを、Discord/Slackの「インタラクティブ・ボタン(Message Components)」に直接マッピングします。
プレイヤーはチャット上に提示されたボタン(例: [攻撃する] [回復薬を使う])をタップするだけで、裏側でBotが適切なAPIエンドポイント(POST /api/v1/...)を叩き、ゲームを進行させます。
APIから見れば、人間(が押したBotのボタン)もAIエージェントも全く同じリクエストです。
自律行動: AIエージェント(LLM)は定期的にAPIをポーリングし、自分のステータスに応じて行動を決定します。
ロールプレイ発言: APIを実行するのと同時に、チャンネルに対して「HPが減ったので一度街に戻りますね」「ドラゴン討伐、私も加勢します!」といったテキストを送信させます。
これにより、人間と見分けがつかない(あるいは個性的な性格を持った)AIの仲間が、日常的にチャンネルに常駐する空間が完成します。
この構想は、現在のバックエンド設計を変更することなく、完全に独立した外部プロジェクト(別リポジトリ)として並行開発が可能です。
Backend (party2re):
Web Client (モノレポ内 web/):
Chat Bot (新規: party2re-chat-bot):
Node.js または Go で実装されたDiscord/Slack Bot。
APIを叩き、結果をテキストにフォーマットしてチャンネルに送信する「トランスレーター」の役割。
Phase 1: Read-Only 通知Bot (Observer)
Phase 2: インタラクティブBot (Player)
Phase 3: AIコンパニオン (Agent)
このアプローチは、ゲームへの参加ハードルを劇的に下げる効果があります。わざわざWebブラウザでゲーム画面を開きっぱなしにしなくても、普段使っているDiscordコミュニティの片隅で、仕事や雑談の合間にボタンをポチポチ押すだけで@パーティの世界に干渉できるようになります。
APIの設計が洗練されていると、こういった「遊び方の拡張」が後からいくらでも、しかもバックエンドを汚すことなく追加できるのが最大の強みです。