diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7a07986..34dbac7 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,8 +4,8 @@ ## コードコメント・ドキュメント規則 -[#file:../docs/02_Guide/GUIDE_04_コードコメント規則.txt](../docs/02_Guide/GUIDE_04_コードコメント規則.txt) +[#file:../docs/01_GUIDE/GUIDE_04_コードコメント規則.txt](../docs/01_GUIDE/GUIDE_04_コードコメント規則.txt) ## プロトコル追加手順 -[#file:../docs/02_Guide/GUIDE_05_プロトコル追加手順.txt](../docs/02_Guide/GUIDE_05_プロトコル追加手順.txt) +[#file:../docs/01_GUIDE/GUIDE_05_プロトコル追加手順.txt](../docs/01_GUIDE/GUIDE_05_プロトコル追加手順.txt) diff --git a/.github/instructions/code-comment-rules.instructions.md b/.github/instructions/code-comment-rules.instructions.md index f5cf027..ef4a99e 100644 --- a/.github/instructions/code-comment-rules.instructions.md +++ b/.github/instructions/code-comment-rules.instructions.md @@ -4,4 +4,4 @@ # コードコメント・ドキュメント規則 -[#file:../../docs/02_Guide/GUIDE_04_コードコメント規則.txt](../../docs/02_Guide/GUIDE_04_コードコメント規則.txt) +[#file:../../docs/01_GUIDE/GUIDE_04_コードコメント規則.txt](../../docs/01_GUIDE/GUIDE_04_コードコメント規則.txt) diff --git a/.github/instructions/protocol-extension-guide.instructions.md b/.github/instructions/protocol-extension-guide.instructions.md index 4a9a3fe..1713aa8 100644 --- a/.github/instructions/protocol-extension-guide.instructions.md +++ b/.github/instructions/protocol-extension-guide.instructions.md @@ -4,4 +4,4 @@ # プロトコル追加手順 -[#file:../../docs/02_Guide/GUIDE_05_プロトコル追加手順.txt](../../docs/02_Guide/GUIDE_05_プロトコル追加手順.txt) +[#file:../../docs/01_GUIDE/GUIDE_05_プロトコル追加手順.txt](../../docs/01_GUIDE/GUIDE_05_プロトコル追加手順.txt) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5ec339c..d8717a9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "github.copilot.chat.commitMessageGeneration.instructions": [ { - "file": "docs/02_Guide/GUIDE_03_Git運用ルール.txt" + "file": "docs/01_GUIDE/GUIDE_03_Git運用ルール.txt" } ] } diff --git a/CLAUDE.md b/CLAUDE.md index 0a7f2f6..5d147f0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,7 +1,7 @@ # CLAUDE.md このファイルはClaude Codeがコード生成・編集・ドキュメント作成を行う際に従うべきプロジェクトルールを定義する. -各ルールの詳細は `docs/02_Guide/` 配下の対応ファイルを参照すること. +各ルールの詳細は `docs/01_GUIDE/` 配下の対応ファイルを参照すること. --- @@ -22,7 +22,7 @@ - **改行ルール**: 大見出し前に2行,中見出し・小見出し前に1行空ける - **コマンド**: 先頭に `$ ` を付ける -詳細: `docs/02_Guide/GUIDE_01_ドキュメント作成ガイド.txt` +詳細: `docs/01_GUIDE/GUIDE_01_ドキュメント作成ガイド.txt` --- @@ -48,7 +48,7 @@ - 拡張子: `.txt` - 1ファイル1テーマで分割する -詳細: `docs/02_Guide/GUIDE_02_ファイル命名規則.txt` +詳細: `docs/01_GUIDE/GUIDE_02_ファイル命名規則.txt` --- @@ -89,7 +89,7 @@ - `main` への直接コミット・直接プッシュは禁止(必ずPR経由) - 作業ブランチのベースは常に最新の `main` から作成する -詳細: `docs/02_Guide/GUIDE_03_Git運用ルール.txt` +詳細: `docs/01_GUIDE/GUIDE_03_Git運用ルール.txt` --- @@ -143,7 +143,7 @@ - ファイル内部でのみ使用し,外部に公開されない型・関数・定数 - コード自体が自明な場合 -詳細: `docs/02_Guide/GUIDE_04_コードコメント規則.txt` +詳細: `docs/01_GUIDE/GUIDE_04_コードコメント規則.txt` --- @@ -180,4 +180,25 @@ - `events.ts` に型本体を置かない(再公開専用を維持する) -詳細: `docs/02_Guide/GUIDE_05_プロトコル追加手順.txt` +詳細: `docs/01_GUIDE/GUIDE_05_プロトコル追加手順.txt` + +--- + +## 6. ディレクトリ構造ドキュメントの更新 (ENV_02) + +ファイル・ディレクトリの**追加・削除・移動**を行った場合は,`docs/02_ENV/ENV_02_ディレクトリ構造.txt` を合わせて更新すること. + +- 対象: `apps/client/src`,`apps/server/src`,`packages/shared/src` 配下の変更 +- 既存の記載粒度(代表的なファイル・フォルダのみ)に合わせて追記・修正する +- ファイル単体の追加でも,同階層に未記載のディレクトリが生じた場合は追記する + +--- + +## 7. ゲーム定数変更時のSPEC更新 + +`packages/shared/src/config/gameConfig.ts` の定数値を変更した場合は,`docs/04_SPEC/` 配下の対応する仕様書を合わせて更新すること. + +- 対象: `GAME_CONFIG` 内の時間・距離・回数などの数値定数 +- 特に影響が大きいファイル: + - `SPEC_03_ゲームプレイ仕様.txt`(制限時間,ボム・ハリケーン・被弾の各パラメータ) + - `SPEC_04_HUD_UI仕様.txt`(表示切替のしきい値,クールダウン時間) diff --git "a/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" "b/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" deleted file mode 100644 index bb06683..0000000 --- "a/docs/01_Env/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" +++ /dev/null @@ -1,308 +0,0 @@ -======================================================================== -Pixel Paint War - 開発環境・技術スタック定義書 -======================================================================== - -1. プロジェクト基本方針 ------------------------------------------------------------------------- - -1-1. アーキテクチャ構成: Monorepo (モノレポ) - ・目的: クライアント(Client)とサーバー(Server)で,言語(TypeScript)およびゲームロジック(移動演算・定数・型定義)を完全共有するため. - ・パッケージ管理: pnpm workspaces を採用. - -1-2. コア・コンセプト - ・言語: TypeScript (Strict mode) - ・通信: WebSocket + Hybrid Protocol - - Core Game (移動・塗り): Custom Binary (DataView) による極小パケット通信 - - Meta Data (ロビー・チャット): JSON (開発効率とデバッグ容易性を優先) - ・描画: WebGL 2D (Pixi.js) - ・同期: サーバー権限 (Authoritative) + クライアント予測 (Prediction) - -1-3. AI活用型開発 (AI-Assisted Development) - ・採用ツール: - - Gemini Pro (学校提供ライセンス) - - GitHub Copilot Pro (GitHub Student Developer Pack) - ・言語選定の優位性: - TypeScriptを採用することで厳密な型定義(Type/Interface)を保持する. - これによりAIがコードの文脈や意図を正確に解釈可能となり, - 型のないJavaScriptと比較して,コード生成・補完・リファクタリングの精度が著しく向上する. - - -2. ディレクトリ構造 (Directory Structure) ------------------------------------------------------------------------- - -2-1. 構成一覧 - root/ - ├── .devcontainer/ - │ └── devcontainer.json # 開発コンテナ設定 - ├── apps/ - │ ├── client/ # 【演出】フロントエンド (Browser) - │ │ ├── .gitignore # 除外設定 - │ │ ├── index.html # HTMLエントリ - │ │ ├── package.json # 依存・スクリプト - │ │ ├── public/ - │ │ │ └── vite.svg # 公開アイコン - │ │ ├── src/ - │ │ │ ├── app.tsx # ルートUI - │ │ │ ├── index.css # 全体スタイル - │ │ │ ├── main.tsx # 起動エントリ - │ │ │ ├── assets/ - │ │ │ │ └── preact.svg # ロゴ素材 - │ │ │ ├── hooks/ - │ │ │ │ └── useAppFlow.ts # 画面遷移フック - │ │ │ ├── network/ - │ │ │ │ ├── SocketManager.ts # WSクライアント - │ │ │ │ └── handlers/ - │ │ │ │ ├── CommonHandler.ts # 共通WSハンドラ - │ │ │ │ ├── GameHandler.ts # ゲームWSハンドラ - │ │ │ │ ├── LobbyHandler.ts # ロビーWSハンドラ - │ │ │ │ └── TitleHandler.ts # タイトルWSハンドラ - │ │ │ └── scenes/ - │ │ │ ├── game/ - │ │ │ │ ├── GameInputManager.ts # 入力管理 - │ │ │ │ ├── GameManager.ts # ゲーム制御 - │ │ │ │ ├── GameScene.tsx # ゲーム画面 - │ │ │ │ ├── GameView.tsx # ゲーム描画 - │ │ │ │ ├── entities/ - │ │ │ │ │ ├── map/ - │ │ │ │ │ │ ├── GameMapController.ts # マップ制御 - │ │ │ │ │ │ ├── GameMapModel.ts # マップモデル - │ │ │ │ │ │ └── GameMapView.ts # マップ描画 - │ │ │ │ │ └── player/ - │ │ │ │ │ ├── PlayerController.ts # プレイヤー制御 - │ │ │ │ │ ├── PlayerModel.ts # プレイヤーモデル - │ │ │ │ │ └── PlayerView.ts # プレイヤー描画 - │ │ │ │ └── input/ - │ │ │ │ ├── joystick/ - │ │ │ │ │ ├── JoystickInputPresenter.tsx # 仮想スティックUI - │ │ │ │ │ ├── JoystickModel.ts # スティックモデル - │ │ │ │ │ ├── JoystickView.tsx # スティック描画 - │ │ │ │ │ └── common/ - │ │ │ │ │ ├── index.ts # スティック共通 - │ │ │ │ │ ├── joystick.constants.ts # スティック定数 - │ │ │ │ │ └── joystick.types.ts # スティック型 - │ │ │ │ ├── useJoystickController.ts # スティック制御フック - │ │ │ │ └── useJoystickState.ts # スティック状態 - │ │ │ ├── lobby/ - │ │ │ │ └── LobbyScene.tsx # ロビー画面 - │ │ │ └── title/ - │ │ │ └── TitleScene.tsx # タイトル画面 - │ │ ├── tsconfig.app.json # アプリTS設定 - │ │ ├── tsconfig.json # TS親設定 - │ │ ├── tsconfig.node.json # Node向けTS設定 - │ │ └── vite.config.ts # Vite設定 - │ └── server/ # 【権限】バックエンド (Node.js) - │ ├── package.json # 依存・スクリプト - │ ├── tsconfig.json # TS設定 - │ └── src/ - │ ├── index.ts # サーバー起点 - │ ├── logging/ - │ │ └── logEvent.ts # 共通ログ出力 - │ ├── domains/ - │ │ ├── game/ - │ │ │ ├── GameLoop.ts # 固定ループ - │ │ │ ├── GameManager.ts # ゲーム状態管理 - │ │ │ ├── application/ - │ │ │ │ ├── ports/ # ユースケース入出力境界 - │ │ │ │ ├── services/ # ゲームアプリケーションサービス - │ │ │ │ └── useCases/ # ゲームユースケース - │ │ │ ├── entities/ - │ │ │ │ └── Player.ts # サーバーPlayer - │ │ │ └── states/ - │ │ │ └── MapStore.ts # マップ状態保持 - │ │ └── room/ - │ │ ├── application/ - │ │ │ ├── ports/ # ユースケース入出力境界 - │ │ │ ├── services/ # ルームアプリケーションサービス - │ │ │ └── useCases/ # ルームユースケース - │ │ └── RoomManager.ts # ルーム管理 - │ └── network/ - │ ├── SocketManager.ts # WS接続管理 - │ ├── adapters/ - │ │ └── socketEmitters.ts # 送信アダプタ - │ ├── handlers/ - │ │ ├── CommonHandler.ts # 共通WSハンドラ - │ │ ├── GameHandler.ts # ゲームWSハンドラ(中間層) - │ │ ├── RoomHandler.ts # ルームWSハンドラ(中間層) - │ │ ├── game/ - │ │ │ ├── handleGameDisconnect.ts # ゲーム切断処理配線 - │ │ │ └── registerGameHandlers.ts # ゲーム受信イベント配線 - │ │ └── room/ - │ │ ├── handleRoomDisconnect.ts # ルーム切断処理配線 - │ │ └── registerRoomHandlers.ts # ルーム受信イベント配線 - │ ├── bootstrap/ - │ │ ├── createHttpServer.ts # HTTP生成 - │ │ ├── createIo.ts # Socket.IO生成 - │ │ └── boot.ts # 起動配線 - ├── docs/ - │ ├── 01_Env/ - │ │ ├── ENV_01_環境構築・技術スタック.txt # 環境・技術定義 - │ │ ├── ENV_02_環境構築手順書.txt # 初期構築手順 - │ │ ├── ENV_03_TypeScript概要.txt # TS基礎説明 - │ │ ├── ENV_04_スマホ実機デバッグ手順.txt # 実機デバッグ手順 - │ │ ├── ENV_05_Docker運用操作ガイド.txt # Docker運用手順 - │ │ ├── ENV_06_管理者用環境構築手順.txt # 管理者向け手順 - │ │ └── ENV_07_テスト操作手順.txt # テスト操作手順 - │ ├── 02_Guide/ - │ │ ├── GUIDE_01_ドキュメント作成ガイド.txt # 文書作成ルール - │ │ ├── GUIDE_02_ファイル命名規則.txt # 命名規則 - │ │ ├── GUIDE_03_Git運用ルール.txt # Git運用ルール - │ │ └── GUIDE_04_コードコメント規則.txt # コメント運用ルール - │ ├── 03_Plan/ - │ │ └── PLAN_01_移動テスト実装計画.txt # 実装計画 - │ └── 04_Spec/ - │ └── SPEC_03_プロトタイプ_移動テスト.txt # 機能仕様 - ├── packages/ - │ └── shared/ # 【最重要】「真実」の定義場所(型、定数、純粋ロジック) - │ ├── package.json # 依存・公開設定 - │ ├── tsconfig.json # TS設定 - │ └── src/ - │ ├── index.ts # 共有エクスポート - │ ├── config/ - │ │ ├── index.ts # 設定エクスポート - │ │ ├── gameConfig.ts # 共通定数 - │ │ └── networkConfig.ts # 通信設定 - │ ├── domains/ - │ │ ├── app/ - │ │ │ ├── app.const.ts # アプリ定数 - │ │ │ └── app.type.ts # アプリ型 - │ │ ├── gridMap/ - │ │ │ ├── gridMap.logic.ts # マップ計算 - │ │ │ └── gridMap.type.ts # マップ型定義 - │ │ ├── player/ - │ │ │ └── player.type.ts # プレイヤー型 - │ │ └── room/ - │ │ ├── room.const.ts # ルーム定数 - │ │ └── room.type.ts # ルーム型 - │ └── protocol/ - │ └── events.ts # 通信イベント定義 - ├── test/ # テスト用スクリプト群 - │ ├── load-bot.constants.ts # 負荷テスト定数 - │ ├── load-bot.ts # 負荷テスト実行 - │ ├── node_modules/ # テスト依存 - │ ├── package.json # テスト依存・スクリプト - │ └── tsconfig.json # テストTS設定 - ├── .gitignore # Git除外設定 - ├── .npmrc # pnpm設定 - ├── docker-compose.prod.yml # 本番Compose定義 - ├── docker-compose.yml # 開発Compose定義 - ├── Dockerfile # 本番イメージ定義 - ├── package.json # ワークスペース定義 - ├── pnpm-lock.yaml # lockファイル - ├── pnpm-workspace.yaml # workspace設定 - └── README.md # プロジェクト概要 - - ※ 右側コメントは,役割が一行で分かる短文で記載する. - - ※ shared は client/server 両方から import して使用する. - - -3. 技術スタック詳細 (Tech Stack) ------------------------------------------------------------------------- - -3-1. 共通・基盤 (Common / Shared) - ・Runtime: Node.js (v20 LTS 以上) - ・Package Manager: pnpm - ・Build Tool: tsup (高速で軽量なTypeScriptバンドラ) - ・Serialization: Custom Binary (Standard DataView API) - - 採用理由: ライブラリ依存をなくし,仕様書要件(30KB/s以下)を満たす最適化を行うため. - - 用途: 座標データ,入力情報の圧縮通信. - -3-2. フロントエンド (Client) - ・Build Tool: Vite - ・Language: TypeScript - ・Rendering Engine: Pixi.js (v8) - - 採用理由: 50人同時対戦時の大量のスプライト描画と60fps維持のため. - ・UI Library: Preact (または Vanilla HTML/CSS) - - 採用理由: ゲームループへの負荷を避けつつ,軽量なHUDを構築するため. - ・Network: socket.io-client - -3-3. バックエンド (Server) - ・Runtime: Node.js - ・Execution: tsx (開発時の高速実行・ウォッチ用) - ・WebSocket Library: Socket.IO - - 採用理由: 接続管理・イベント配線を明確化しやすく,Client 側 (socket.io-client) と整合するため. - ・Logic: 独自ループ (20Hz固定) - - Physics Engine: 使用しない (shared/physics.ts による独自グリッド判定) - -3-4. 開発ツール (Dev Tools) - ・Linter: ESLint - ・Formatter: Prettier - ・Test: Vitest (共通ロジックの単体テスト用) - ・AI Assistant: GitHub Copilot Pro, Gemini Pro - -3-5. インフラ・コンテナ技術 (Infrastructure) - ・Containerization: Docker - - 採用理由: 開発環境(Dev Containers)と本番環境の差異を排除するため. - ・Orchestration: - - Dev: Docker Compose (ボリュームマウントによるホットリロード) - - Prod: Docker Compose (再起動ポリシーとポート開放のみの最小構成) - ・Deployment Image: Multi-stage Build (Node.js Slim) - - ビルド戦略: - 1. Builderステージ: 全依存をインストールし,TypeScript (Shared -> Server) をコンパイル. - 2. Prune: `pnpm prune --prod` により開発依存を削除. - 3. Copy: pnpmの仕様(シンボリックリンク)に対応するため,`node_modules` を明示的にコピーする. - 4. Runnerステージ: 必要な `dist` と `node_modules` のみをコピーし,イメージサイズを最小化する. - - -4. 開発マシンの前提条件 (Prerequisites) ------------------------------------------------------------------------- -本プロジェクトは Docker (Dev Containers) による開発環境統一を推奨する. -これにより、ホストOS(Windows/Mac)の環境を汚さずに構築が可能となる。 - -4-1. 【必須】ホストマシンにインストールするもの - 以下のツールのみ,開発者のPC(ホストOS)にインストールが必要である. - - 1. Docker実行環境 - - Docker Desktop (最新版) - - WSL2 (Windowsの場合必須) - - 2. エディタ - - VS Code (Visual Studio Code) - - 3. VS Code 拡張機能 - - Dev Containers (ID: ms-vscode-remote.remote-containers) - ※ これが「必須」である.これさえあれば,以下の開発ツール群は自動セットアップされる. - - 4. アカウント・AI - - GitHub Copilot Pro (Student) - - Gemini Pro (学校提供ライセンス) - -4-2. 【自動】コンテナ内に構築されるもの (インストール不要) - 以下のツールは `devcontainer.json` に定義済みであり,コンテナ起動時に - 自動的にインストール・設定されるため,手動導入は不要である. - - 1. Runtime & Package Manager - - Node.js (v20.x LTS) - - pnpm (Latest) - - 2. VS Code 拡張機能 (コンテナ内) - - ESLint - - Prettier - - EditorConfig - - Hex Editor - - ※ ホスト側で `node -v` や `pnpm -v` を実行する必要はなく, - 全て VS Code の「ターミナル (コンテナ接続済)」で行う. - - -5. 実装上の重要ルール (Implementation Rules) ------------------------------------------------------------------------- - -5-1. ロジックの一元管理 - - 「移動速度」「ヒット判定」「マップ更新」の計算式は必ず `packages/shared` に記述する. - - Client と Server で別の計算式を書くことを禁止する(同期ズレ防止). - -5-2. 座標系 - - 内部計算: Float (浮動小数点) - - 通信データ: Integer (整数 / 100倍して送信など圧縮を考慮) - - 描画: Float (補間処理あり) - -5-3. 依存方向 - - OK: Client -> Shared - - OK: Server -> Shared - - NG: Client -> Server / Server -> Client (直接参照禁止) - -5-4. 通信境界の責務分離 - - SocketEvents の解決(イベント名の参照)は `apps/server/src/network` 配下に集約する. - - `apps/server/src/domains` 配下では `protocol` を直接 import せず,意味名の Publisher 関数を受け取って利用する. - - Socket の接続制御・受信イベント登録・切断順序制御は network 層が担当し,業務ロジック判断は domain 層が担当する. \ No newline at end of file diff --git "a/docs/01_Env/ENV_02_\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206\346\233\270.txt" "b/docs/01_Env/ENV_02_\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206\346\233\270.txt" deleted file mode 100644 index eb01c3b..0000000 --- "a/docs/01_Env/ENV_02_\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206\346\233\270.txt" +++ /dev/null @@ -1,246 +0,0 @@ -======================================================================== -Pixel Paint War - 開発環境利用ガイド (Development Environment Guide) -======================================================================== - -1. 事前準備 (Prerequisites) ------------------------------------------------------------------------- - -1-1. 目的 - 本ドキュメントは,「Pixel Paint War」の開発に参加する全メンバー向けの - 環境構築および利用ガイドである. - Monorepo構成とDocker(Dev Containers)を使用し,迅速に開発を開始する手順を記す. - -1-2. 【全員必須】 共通ツールのインストール - 開発メンバー全員(管理者・参加者問わず)が以下のツールをインストールする. - - 1. Docker Engine (Linux環境) - ・開発環境の実体(コンテナ)を動かすために必須である. - - ・インストール手順 (Ubuntu/Debian系の例): - ターミナルで以下のコマンドを順に実行する. - - # 1. 公式GPG鍵とリポジトリのセットアップ - sudo apt-get update - sudo apt-get install -y ca-certificates curl gnupg - sudo install -m 0755 -d /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg - sudo chmod a+r /etc/apt/keyrings/docker.gpg - - echo \ - "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ - "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ - sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - - # 2. パッケージのインストール - sudo apt-get update - sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin - - # 3. ユーザー権限の設定 (重要: VS Codeからsudoなしで利用するために必須) - sudo usermod -aG docker $USER - newgrp docker - - ・確認コマンド: - $ docker -v - # Docker version 20.x.x 等と表示されること - - 2. VS Code (Visual Studio Code) - ・メインのエディタとして使用する.最新版をインストールすること. - - 3. VS Code 拡張機能: "Dev Containers" - ・ID: ms-vscode-remote.remote-containers - ・拡張機能マーケットプレイスで検索し、インストールする. - ・これを入れることで、Dockerコンテナ内でVS Codeを開くことが可能になる. - - -2. 環境セットアップ (Setup) ------------------------------------------------------------------------- - - ■ リポジトリのクローン - 1. ソースコードの取得 - 任意のディレクトリで以下のコマンドを実行する. - $ git clone - - 2. ディレクトリ移動 - $ cd SkillSemiWebGame - - 3. 完了 - これだけで準備は完了である. - パッケージのインストール等はDocker起動時に自動で行われるため、 - 手動での `pnpm install` 等は不要である. - - -3. 開発環境(Dev Container)の起動 (Launch) ------------------------------------------------------------------------- - -3-1. プロジェクトを開く - 1. VS Codeを起動し,「ファイル > フォルダを開く」からプロジェクトルートを選択する. - -3-2. コンテナでの再起動 (Reopen in Container) - 以下のいずれかの方法で,開発環境をコンテナ内に移行する. - - 【方法A: ステータスバーから】 - 1. ウィンドウ左下の緑色(または青色)の「><」アイコンをクリックする. - 2. 表示されるメニューから「Reopen in Container」を選択する. - - 【方法B: コマンドパレットから】 - 1. [F1] または [Ctrl+Shift+P] を押下する. - 2. "Reopen" と入力し,「Dev Containers: Reopen in Container」を選択する. - - ※ トラブルシューティング: - もし起動後に node_modules が見つからない等のエラーが出た場合は, - 「Reopen」ではなく「Dev Containers: Rebuild Container」を選択して - 環境を完全に作り直してください. - -3-3. 初回ビルドの待機 - 1. 初回起動時は Dockerイメージのビルドと npmパッケージのインストールが行われる. - (数分〜十数分かかる場合がある) - 2. 右下に "Starting Dev Container" 等の通知が表示されている間は待機する. - -3-4. 起動確認 - 1. 左下のアイコンが「Dev Container: Pixel Paint War Dev」と表示されていることを確認する. - 2. VS Codeのターミナルを開き (`Ctrl + @`),パスを確認する. - - 成功例: node@...:/workspace$ - (Windowsのパス C:\Users... ではなく Linux形式になっていれば成功) - - 3. 動作確認コマンドを実行する. - $ pnpm --filter client dev - - ※ エラー時の対応: - 「sh: vite: not found」等のエラーが出る場合は,自動インストールが完了していない可能性があります. - ターミナルで `pnpm install` を手動実行するか,上記 3-2 の「Rebuild Container」を試してください. - - ・ブラウザでの確認: - ターミナルに「➜ Local: http://localhost:5173/」と表示されたら, - Google Chrome等のブラウザを開き,アドレスバーに上記URLを貼り付けて実行する. - - ・正常動作の判断基準: - 画面に「Vite + Preact」のロゴと「Vite + Preact + TypeScript」といった - テキストが表示されていれば,フロントエンドの環境構築は成功である. - - -4. 開発ツールの確認 (Tools Verification) ------------------------------------------------------------------------- -Dockerコンテナ起動完了後、定義済みのツールが正しく自動導入されているか確認する. -※ 手動でのインストールは不要である. - -4-1. VS Code 拡張機能 - 拡張機能サイドバーを開き、"Dev Container: Pixel Paint War Dev" セクションに - 以下がインストール済みであることを確認する. - ・ESLint - ・Prettier - Code formatter - ・EditorConfig for VS Code - ・Hex Editor - ・GitHub Copilot - -4-2. AI アシスタント設定 - GitHub Copilot Pro - - VS Code 右下のアイコンから、GitHubアカウントへのログイン状態を確認する. - - -5. 構成確認 (Project Structure) ------------------------------------------------------------------------- - -5-1. ディレクトリ構成 - コンテナ内で以下のディレクトリ構造が見えていることを確認する. - - SkillSemiWebGame/ <-- プロジェクトルート - ├── .devcontainer/ <-- Docker設定 - ├── .git/ - ├── docker-compose.yml <-- Docker構成 - ├── package.json <-- ルート定義 - ├── pnpm-workspace.yaml <-- ワークスペース定義 - ├── node_modules/ <-- 依存ライブラリ - │ - ├── apps/ <-- アプリケーション格納用 - │ ├── client/ <-- フロントエンド (Vite + Preact) - │ │ ├── src/ - │ │ │ ├── main.tsx - │ │ │ └── ... - │ │ ├── package.json <-- pixi.js, @repo/shared 依存あり - │ │ └── vite.config.ts - │ │ - │ └── server/ <-- バックエンド (Node.js) - │ ├── src/ - │ │ └── index.ts <-- エントリーポイント - │ └── package.json <-- ws, @repo/shared 依存あり - │ - └── packages/ <-- 共通パッケージ格納用 - └── shared/ <-- 共通ロジック - ├── dist/ <-- ビルド成果物 - ├── src/ - │ └── index.ts - └── package.json - -6. 動作確認 (Verification) ------------------------------------------------------------------------- - -6-1. ビルド確認 - ※ 注意: 以下のコマンドは全て「Dev Container内のターミナル」で実行すること. - - $ pnpm --filter @repo/shared build - ※ shared のビルドが成功することを確認する. - -6-2. 開発サーバー起動 - モノレポ構成のため,個別のディレクトリに移動せず,プロジェクトルートから - --filter オプションを使用して各アプリを起動する. - ※ ターミナルを2つ開き,両方を同時に起動した状態で開発を進めることを推奨. - - 1.Client (フロントエンド) の動作確認 - ・ルートディレクトリにて以下のコマンドを実行する. - $ pnpm --filter client dev - - ・ブラウザでの確認: - ターミナルに「➜ Local: http://localhost:5173/」と表示されたら, - Google Chrome等のブラウザを開き,アドレスバーに上記URLを貼り付けて実行する. - - ・正常動作の判断基準: - 画面に「Vite + Preact」のロゴと「Vite + Preact + TypeScript」といった - テキストが表示されていれば,フロントエンドの環境構築は成功である. - - 2. Server (バックエンド) の動作確認 - ・テスト用コードの作成: - 動作確認用のエントリーポイントを作成する. - $ touch apps/server/src/index.ts - - ファイルに以下の内容を記述する. - console.log("Server is running!"); - - ・コマンド: - $ pnpm --filter server dev - - ・正常動作の判断基準: - ターミナルに「Server is running!」と出力されれば構築成功である. - - 3.終了方法 (重要) - ・動作確認を終了し,開発サーバーを停止させる場合は,ターミナル上で - 「Ctrl + C」を押下する. - - -7. (応用) 本番ビルドの動作確認 (Production Build Check) ------------------------------------------------------------------------- -開発環境(Dev Container)ではなく,本番環境と同様のDockerイメージを作成し, -正しくビルド・起動できるかを確認する手順である. -「機能開発が終わった後」や「プルリクエストを出す前」に実施することを推奨する. - -7-1. 準備 - Dev Containerを閉じ,ホストOS(Windows/Mac)のターミナルを開く. - ※ Dev Container内からはDockerコマンドが使用できない場合があるため. - -7-2. ビルドと起動 - プロジェクトルートで以下のコマンドを実行する. - - $ docker compose -f docker-compose.prod.yml up -d --build - -7-3. 動作確認 - 1. ログ確認 - $ docker compose -f docker-compose.prod.yml logs -f - Serverが起動していることを確認する. - - 2. ブラウザ確認 - http://localhost:3001 - ※ ポート番号が開発用(3000/5173)と異なり 3001 に設定されている点に注意. - -7-4. 終了と削除 - 確認が終わったら必ず環境を停止・削除する. - $ docker compose -f docker-compose.prod.yml down \ No newline at end of file diff --git "a/docs/01_Env/ENV_03_TypeScript\346\246\202\350\246\201.txt" "b/docs/01_Env/ENV_03_TypeScript\346\246\202\350\246\201.txt" deleted file mode 100644 index e489c79..0000000 --- "a/docs/01_Env/ENV_03_TypeScript\346\246\202\350\246\201.txt" +++ /dev/null @@ -1,90 +0,0 @@ -======================================================================== -TypeScript概要 (TypeScript Overview) -======================================================================== - -1. 概要 (Overview) ------------------------------------------------------------------------- -本プロジェクト(Pixel Paint War)において採用するプログラミング言語「TypeScript」に関する基礎知識,選定理由,およびAI活用開発における優位性を定義する. -本ドキュメントは,開発チーム内での技術認識の統一を目的とする. - - -2. TypeScriptとは (What is TypeScript) ------------------------------------------------------------------------- -Microsoftによって開発されたオープンソースのプログラミング言語である.JavaScriptのスーパーセット(上位互換)として設計されており,大規模なアプリケーション開発に適した機能が拡張されている. - -2-1. JavaScriptとの違い - ・静的型付け (Static Typing): - 変数や関数の引数,戻り値に「型(Type)」を指定できる.JavaScriptは動的型付け言語であり,実行時まで型が決まらないが,TypeScriptはコンパイル(トランスパイル)時に整合性をチェックする. - ・クラスベースオブジェクト指向: - インターフェース(Interface),ジェネリクス(Generics),アクセス修飾子(public/private)など,JavaやC#に近いオブジェクト指向構文をサポートする. - ・コンパイルの必要性: - ブラウザやNode.jsはTypeScriptを直接実行できないため,JavaScriptファイルへ変換(トランスパイル)して使用する. - -2-2. 一般的な利用目的 - ・大規模Webアプリケーション開発: - コード量が増えても型定義により保守性を維持しやすい. - ・チーム開発: - 型定義がそのまま「仕様書」としての役割を果たし,メンバー間の認識齟齬を防ぐ. - ・フルスタック開発: - フロントエンド(React/Vue/Angular等)とバックエンド(Node.js/Deno等)で言語を統一し,型定義を共有する. - - -3. 言語の強み (Strengths) ------------------------------------------------------------------------- - -3-1. 安全性と品質向上 - ・コンパイルエラーによる早期発見: - 「undefinedのプロパティ参照」や「数値と文字列の誤った演算」など,JavaScriptで頻発する実行時エラーを,コードを書いている段階(コンパイル時)で検出できる. - -3-2. 開発効率の向上 - ・強力な入力補完 (IntelliSense): - VS Code等のエディタにおいて,型情報を元にした正確なコード補完,メソッドの候補表示,定義元へのジャンプが可能となる. - ・リファクタリングの容易さ: - 変数名や関数名の変更を行っても,依存する箇所をエディタが一括で修正・検知できるため,改修コストが低い. - - -4. AI活用型開発における利点 (Benefits in AI-Assisted Development) ------------------------------------------------------------------------- -本プロジェクトの方針である「AI活用型開発(Gemini Pro / GitHub Copilot Pro)」において,TypeScriptはJavaScriptと比較して以下の決定的な優位性を持つ. - -■ コンテキストの正確な伝達 - 型定義(Type/Interface)が存在することで,AIは変数の意図やデータ構造を推測ではなく「確定情報」として認識できる.これにより,提案されるコードの精度が向上する. - -■ ハルシネーション(嘘の生成)の抑制 - 存在しないプロパティや誤ったメソッドをAIが提案した場合でも,TypeScriptのコンパイラが即座にエラーを出すため,誤ったコードが実装に含まれるリスクを自動的に排除できる. - -■ 意図の明示化 - 「ENV_01」で定義された `packages/shared` のような共通型定義を参照させることで,AIはクライアント・サーバー間の通信仕様を正確に理解し,一貫性のあるロジックを生成可能となる. - - -5. 歴史と現状 (History and Current Status) ------------------------------------------------------------------------- - -5-1. 歴史 - ・開発者: Anders Hejlsberg(C#やTurbo Pascalの設計者)らが中心となり開発. - ・初版公開: 2012年10月. - ・背景: 当時,大規模化するWebアプリ開発においてJavaScriptの仕様(ES5)では保守が困難であったため,静的型付けの需要が高まっていた. - -5-2. 現在のステータス - ・世界No.1の使用率 (GitHub Octoverse 2025): - 2025年のGitHub年次レポートにおいて,長年トップであったPythonおよびJavaScriptを上回り,世界で最も使用されている言語(第1位)となった. - このランキングは,単なるコードの総量ではなく「貢献者数(Unique Contributors)」に基づいており,現在世界中で最も多くのアクティブユーザーが開発を行っている言語であることを示している. - ・デファクトスタンダード: - 現在,モダンなフロントエンド開発(React, Next.js, Vue.jsなど)において,TypeScriptは標準的な選択肢となっている. - ・普及率: - 「State of JS」などの開発者アンケートにおいて,長年「使用率」および「満足度」で上位を維持している.また,Google社内の標準言語としても採用されている(Alligator等). - - -6. 参考文献 (References) ------------------------------------------------------------------------- -・TypeScript Official Website - https://www.typescriptlang.org/ - -・The State of JS 2022/2023 (Usage & Satisfaction) - https://stateofjs.com/ - -・GitHub Octoverse 2025 - https://octoverse.github.com/ - -・Google Engineering Practices Documentation - https://google.github.io/eng-practices/ \ No newline at end of file diff --git "a/docs/01_Env/ENV_04_\343\202\271\343\203\236\343\203\233\345\256\237\346\251\237\343\203\207\343\203\220\343\203\203\343\202\260\346\211\213\351\240\206.txt" "b/docs/01_Env/ENV_04_\343\202\271\343\203\236\343\203\233\345\256\237\346\251\237\343\203\207\343\203\220\343\203\203\343\202\260\346\211\213\351\240\206.txt" deleted file mode 100644 index 06c1f56..0000000 --- "a/docs/01_Env/ENV_04_\343\202\271\343\203\236\343\203\233\345\256\237\346\251\237\343\203\207\343\203\220\343\203\203\343\202\260\346\211\213\351\240\206.txt" +++ /dev/null @@ -1,122 +0,0 @@ -======================================================================== -スマホ実機デバッグ手順 (Smartphone Debugging Guide) -======================================================================== - - -1. 概要 (Overview) ------------------------------------------------------------------------- - -1-0. 目的 - 本ドキュメントは,開発中のWebゲーム「Pixel Paint War」をスマホ実機で動作 - 確認するための手順書である. - 学校や組織のネットワーク(Fortinet等)による制限や,WSL2特有のネットワー - クの壁を回避するため,トンネリングツール「ngrok」を使用した外部公開手順 - を採用する. - -1-1. 前提条件 - ・WSL2 (Ubuntu等) 上で開発環境が構築済みであること. - ・ngrok の公式サイトでアカウント作成済みであること. - ・Authtoken (認証トークン) が取得済みであること. - - -2. ngrokのインストール (Installation) ------------------------------------------------------------------------- -Linux (WSL2) 環境へのインストール手順を記述する. -※ apt パッケージマネージャ経由ではエラーが発生しやすいため,バイナリ直接 -インストール方式を採用する. - -2-1. ダウンロードと配置 - 1. 圧縮ファイルのダウンロード - ターミナルで以下のコマンドを実行し,Linux版バイナリを取得する. - $ wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz - - 2. 解凍とインストール - ダウンロードしたファイルを解凍し,実行パスの通ったディレクトリに移動する. - $ sudo tar xvzf ngrok-v3-stable-linux-amd64.tgz -C /usr/local/bin - - 3. 動作確認 - バージョン情報が表示されるか確認する. - $ ngrok --version - ※ "ngrok version 3.x.x" 等と表示されれば成功である. - -2-2. アカウント認証 (Authentication) - ngrok のダッシュボード (https://dashboard.ngrok.com/get-started/your-authtoken) - からトークンを確認し,以下のコマンドで設定する. - - ■ トークンの登録 - $ ngrok config add-authtoken [あなたのAuthtoken] - ※ "[あなたのAuthtoken]" の部分は実際の文字列に置き換える. - - -3. デバッグ実行手順 (Execution Steps) ------------------------------------------------------------------------- - -3-1. Client設定の修正 (Update Configuration) - 開発サーバーが外部 (ngrok) からの接続を受け付けるよう,設定を変更する. - - ■ package.json の編集 - `apps/client/package.json` を開き,`scripts` ブロックの `dev` コマンドに `--host` オプションを追加する. - - [修正前] - "dev": "vite" - - [修正後] - "dev": "vite --host" - -3-2. 開発サーバーの起動 (Launch Dev Server) - まず,ローカル環境でアプリケーションを起動する. - - ■ Clientアプリの起動 - プロジェクトルートで以下のコマンドを実行する. - $ pnpm --filter client dev - ※ ターミナルに `Network: http://x.x.x.x:5173/` と表示されれば設定成功である. - -3-3. ngrokによる公開 (Expose via ngrok) - 新しいターミナルウィンドウを開き,以下の手順でトンネルを作成する. - - 1. ngrokの起動 - Vite の Host ヘッダーチェックを回避するため,オプションを付与して実行する. - $ ngrok http 5173 --host-header="localhost" - - 2. 公開URLの確認 - 起動後に表示されるステータス画面から,"Forwarding" の行を確認する. - - Session Status online - Account User Name (Plan: Free) - Forwarding https://xxxx-xxxx.ngrok-free.app -> http://localhost:5173 - - 上記の "https://xxxx-xxxx.ngrok-free.app" が公開URLとなる. - -3-4. スマホからのアクセス (Access from Smartphone) - 1. URLの共有 - 発行された URL をスマホに送信する(QRコード作成ツールやチャット等を使用). - - 2. ブラウザでの確認 - スマホのブラウザ(Chrome,Safari等)で URL にアクセスする. - タイトル画面が表示されれば接続成功である. - - -4. 注意事項とトラブルシューティング (Notes & Troubleshooting) ------------------------------------------------------------------------- - -4-1. Freeプランの制限 - ・同時接続数: Freeプランでは同時に1つのポートしか公開できない. - ・Client/Server構成の注意: - 本手順ではフロントエンド (Port 5173) のみ公開している. - バックエンド (Port 3000) への WebSocket 通信が必要な場合,ゲーム開始時 - に接続エラーとなる可能性がある. - - 対策: UIレイアウトや描画負荷の確認を主目的として使用する. - -4-2. エラー対応 - ■ "ERR_NGROK_3200" (Tunnel already open) - ・既に別のターミナルで ngrok が起動している場合に発生する. - - 対策: 起動中の ngrok を終了 (Ctrl + C) してから再実行する. - - ■ "Invalid Host Header" (画面が真っ白になる) - ・Vite が不正なドメインからのアクセスを拒否している. - - 対策: 起動コマンドに `--host-header="localhost"` が含まれているか再確認する. - - ■ "ERR_CERT_AUTHORITY_INVALID" (Fortinet等の警告) - ・ngrok を使用せずローカルIPで接続しようとした場合に,組織内ネットワーク - のセキュリティ機器にブロックされる現象である. - - 対策: 必ず本手順の ngrok 経由 (https) で接続する. \ No newline at end of file diff --git "a/docs/01_Env/ENV_05_Docker\351\201\213\347\224\250\346\223\215\344\275\234\343\202\254\343\202\244\343\203\211.txt" "b/docs/01_Env/ENV_05_Docker\351\201\213\347\224\250\346\223\215\344\275\234\343\202\254\343\202\244\343\203\211.txt" deleted file mode 100644 index be89f13..0000000 --- "a/docs/01_Env/ENV_05_Docker\351\201\213\347\224\250\346\223\215\344\275\234\343\202\254\343\202\244\343\203\211.txt" +++ /dev/null @@ -1,82 +0,0 @@ -======================================================================== -Docker 運用・操作ガイド (Docker Operations Guide) -======================================================================== - -1. 目的 (Objective) ------------------------------------------------------------------------- -本ドキュメントは,Pixel Paint War プロジェクトにおける Docker の日常的な -操作コマンドと,トラブルシューティング手順をまとめたものである. -本プロジェクトでは「開発環境」と「本番環境」で異なる運用を行う. - - -2. 開発環境 (Development Environment) ------------------------------------------------------------------------- -VS Code の Dev Containers 機能を使用する. - -2-1. -基本操作 - ・起動: VS Code でプロジェクトを開き,「Reopen in Container」を実行する. - ・停止: VS Code を閉じる(自動的に停止する). - ・ターミナル: VS Code 内のターミナルを使用する. - -2-2. -コンテナの再構築 (Rebuild) - 依存関係の不整合や設定変更が反映されない場合に実行する. - 1. コマンドパレット (F1) を開く. - 2. 「Dev Containers: Rebuild Container」を選択する. - 3. キャッシュを無視したい場合は「Rebuild Without Cache」を選択する. - - -3. 本番環境 (Production Environment) ------------------------------------------------------------------------- -手動で Docker Compose コマンドを実行する. -※ 必ず WSL (Windows) または ホストOSのターミナルで実行すること. - -3-1. -基本コマンド - ■ 起動 (ビルド込み) - $ docker compose -f docker-compose.prod.yml up -d --build - - ■ 状態確認 - $ docker compose -f docker-compose.prod.yml ps - - ■ ログ確認 (リアルタイム) - $ docker compose -f docker-compose.prod.yml logs -f - - ■ 停止 - $ docker compose -f docker-compose.prod.yml down - -3-2. -ポート仕様 - ・ホスト側ポート: 3001 - ・コンテナ内ポート: 3000 - ・接続確認URL: http://localhost:3001 - ※ 開発用コンテナ (Port 3000) との衝突を避けるため,3001番を使用する. - - -4. トラブルシューティング (Troubleshooting) ------------------------------------------------------------------------- - -4-1. -ビルドエラー・反映漏れへの対処 - 修正したコードが反映されない,または原因不明のエラーが出る場合, - キャッシュを使わずに強制的に再ビルドを行う. - - $ docker compose -f docker-compose.prod.yml build --no-cache - $ docker compose -f docker-compose.prod.yml up -d --force-recreate - -4-2. -モジュールが見つからない (MODULE_NOT_FOUND) - 本番起動時に `ws` 等が見つからないエラーが出る場合,`Dockerfile` の - COPY記述を確認する.pnpm のシンボリックリンク構造に対応するため, - 以下が記述されている必要がある. - - COPY --from=builder /app/apps/server/node_modules ./apps/server/node_modules - -4-3. -再起動ループ (Restarting) - `docker ps` でステータスが `Restarting` になる場合,サーバープロセスが - クラッシュまたは終了している. - 1. ログを確認する: - $ docker compose -f docker-compose.prod.yml logs --tail=50 - 2. コード修正後,4-1 の手順で再デプロイする. \ No newline at end of file diff --git "a/docs/01_Env/ENV_06_\347\256\241\347\220\206\350\200\205\347\224\250\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" "b/docs/01_Env/ENV_06_\347\256\241\347\220\206\350\200\205\347\224\250\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" deleted file mode 100644 index 3b39784..0000000 --- "a/docs/01_Env/ENV_06_\347\256\241\347\220\206\350\200\205\347\224\250\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" +++ /dev/null @@ -1,346 +0,0 @@ -======================================================================== -Pixel Paint War - 管理者用環境構築手順 (Admin Setup Guide) -======================================================================== - -1. はじめに (Introduction) ------------------------------------------------------------------------- - 本ドキュメントは,プロジェクトを「ゼロから新規作成・再構築する管理者」向けの - Monorepo構成およびDocker環境の構築ログである. - ※ 一般の開発メンバー(Git Cloneして参加する人)は本ドキュメントを実施不要である. - -2. 管理者用事前準備 (Prerequisites for Admin) ------------------------------------------------------------------------- - -2-1. プロジェクト作成用ツールのインストール - 1. Node.js (v20.x LTS) - ・Nodesource リポジトリを使用してインストールする. - - # リポジトリのセットアップとインストール - $ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - - $ sudo apt-get install -y nodejs - - ・確認コマンド: - $ node -v # v20.x.x と表示されること - - 2. pnpm (Package Manager) - ・Node.js 標準の npm ではなく pnpm を使用する. - ・Corepack (Node.js同梱) を有効化してインストールする. - $ sudo corepack enable - $ corepack prepare pnpm@latest --activate - - ・確認コマンド: - $ pnpm -v - - -3. 新規プロジェクト構築 (Project Initialization) ------------------------------------------------------------------------- - -3-1. プロジェクト初期化 - 1. ディレクトリ作成 - $ mkdir SkillSemiWebGame - $ cd SkillSemiWebGame - - 2. Git/pnpm 初期化 - $ git init - $ pnpm init - -3-2. Monorepo構成設定 - 1. pnpm-workspace.yaml 作成 - ルート直下に作成し、以下を記述する. - packages: - - 'apps/*' - - 'packages/*' - - 2. .npmrc 作成 - ルート直下に作成し、以下を記述する. - shamefully-hoist=true - -3-3. ディレクトリ構造の構築 - 以下の構成になるようにディレクトリを作成する. - - root/ - ├── apps/ - │ ├── client/ # フロントエンド (Browser) - │ └── server/ # バックエンド (Node.js) - └── packages/ - └── shared/ # 共通ロジック (Shared Library) - - ・作成コマンド例: - $ mkdir -p apps/client apps/server packages/shared - -3-4. Git除外設定 (.gitignore) - ルート直下に `.gitignore` を作成し、以下を記述する. - - node_modules/ - .pnpm-store/ - dist/ - build/ - .env - .DS_Store - .vscode/* - !.vscode/extensions.json - !.vscode/launch.json - coverage/ - !packages/ - - -4. アプリケーション雛形の作成 (Scaffolding) ------------------------------------------------------------------------- - -4-1. 共通ライブラリ (packages/shared) - 1. 初期化とビルドツール導入 - $ cd packages/shared - $ pnpm init - $ pnpm add -D typescript tsup - - 2. 設定ファイルの調整 (package.json) - ・name: "@repo/shared" と命名する(推奨). - ・main: "./dist/index.js", types: "./dist/index.d.ts" を指定する. - ・scripts: "build": "tsup src/index.ts --format cjs,esm --dts" を追加する. - - 3. エントリーポイントの作成 - $ mkdir src - $ touch src/index.ts - ※ (例: export * from './constants';) - - 4. TypeScript設定ファイルの作成 (tsconfig.json) - ・ファイル: packages/shared/tsconfig.json - ・内容: - { - "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "Bundler", - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] - } - -4-2. フロントエンド (apps/client) - 1. プロジェクト作成 - $ cd ../../apps/client - $ pnpm create vite . --template preact-ts - ※ Use rolldown-vite? » No - ※ Install with pnpm and start now? » No - - 2. 依存ライブラリのインストール - $ pnpm add pixi.js - $ pnpm add @repo/shared --workspace - -4-3. バックエンド (apps/server) - 1. 初期化 - $ cd ../../apps/server - $ pnpm init - - 2. 依存ライブラリのインストール - $ pnpm add ws - $ pnpm add -D tsx typescript @types/node @types/ws - $ pnpm add @repo/shared --workspace - - 3. サーバー用ディレクトリとファイルの作成 - $ mkdir src - $ touch src/index.ts - - 4. 実行スクリプトの定義 (package.json) - "scripts": { - "dev": "tsx watch src/index.ts" - } - - 5. TypeScript設定ファイルの作成 (tsconfig.json) - ・ファイル: apps/server/tsconfig.json - ・内容: - { - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "lib": ["ES2022"], - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": ".", - "paths": { - "@repo/shared": ["../../packages/shared/src/index.ts"] - } - }, - "include": ["src/**/*"], - "exclude": ["node_modules"] - } - -4-4. 初回コミット (Initial Commit) - 1. ルートに戻る - $ cd ../.. - 2. ステータスの確認 (node_modulesが含まれていないこと) - $ git status - 3. Gitへ保存 - $ git add . - $ git commit -m "chore: Initialize project structure and dependencies" - - -5. Docker環境定義ファイルの作成 (Configuration) ------------------------------------------------------------------------- - -5-1. Dockerfile の作成 - プロジェクトルートに `Dockerfile` を作成する. - ※ Node.js v20 をベースとし,pnpm を有効化した開発用イメージ定義. - - FROM node:20-slim - - # pnpmの準備 - ENV PNPM_HOME="/pnpm" - ENV PATH="$PNPM_HOME:$PATH" - RUN corepack enable - - # 作業ディレクトリ設定 - WORKDIR /workspace - - # 依存関係のコピーとインストール (キャッシュ活用) - COPY . . - RUN pnpm install - - # ポート公開 (Vite:5173, Server:3000) - EXPOSE 5173 3000 - - # デフォルトコマンド (docker-composeで上書きするため待機) - CMD ["sleep", "infinity"] - -5-2. docker-compose.yml の作成 (開発用) - プロジェクトルートに `docker-compose.yml` を作成する. - ※ ローカルのソースコードをコンテナにマウントする設定. - - version: "3.8" - - services: - app: - container_name: pixel-paint-war-dev - # 開発用イメージ: Node.js v20 (定義書準拠) - image: mcr.microsoft.com/devcontainers/typescript-node:20 - - # 永続化とボリュームマウント - volumes: - # カレントディレクトリをコンテナ内の /workspace にマウント - - .:/workspace:cached - # 【重要】node_modules をホスト側と切り離して高速化・安定化させる設定 - - node_modules:/workspace/node_modules - - # コマンドの上書き (コンテナを常時起動させる) - command: sleep infinity - - # ネットワーク設定 - # Client(5173) と Server(3000) のポートを開放 - ports: - - "5173:5173" - - "3000:3000" - - # 環境変数 - environment: - - NODE_ENV=development - - # ユーザー権限 (Nodeイメージ推奨のユーザー) - user: node - - volumes: - node_modules: - -5-3. .devcontainer 設定の作成 - 1. ディレクトリ作成 - $ mkdir .devcontainer - - 2. .devcontainer/devcontainer.json 作成 - VS Codeがコンテナを認識するための設定. - - { - "name": "Pixel Paint War Dev", - "dockerComposeFile": "../docker-compose.yml", - "service": "app", - "workspaceFolder": "/workspace", - - "features": { - "ghcr.io/devcontainers/features/node:1": { - "version": "20", - "pnpm": "latest" - } - }, - - "customizations": { - "vscode": { - "extensions": [ - "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", - "editorconfig.editorconfig", - "ms-vscode.hexeditor", - "github.copilot", - "github.copilot-chat" - ], - "settings": { - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode" - } - } - }, - - // コンテナ起動後の初期化コマンド - // 1. sudo chown ... : node_modules の所有権を node ユーザーに強制変更 - // 2. pnpm install : その後,安全にインストールを実行 - // 3. build : 最後に共通パッケージをビルド - "postCreateCommand": "sudo chown -R node:node /workspace/node_modules && pnpm install && pnpm --filter @repo/shared build", - - // コンテナ内のユーザー - "remoteUser": "node" - } - -5-4. docker-compose.prod.yml の作成 (本番確認用) - プロジェクトルートに `docker-compose.prod.yml` を作成する. - ※ 本番ビルド確認用にポートをずらし、ビルドコマンドを実行する設定. - - services: - app: - build: . - ports: - - "3001:3000" - environment: - - NODE_ENV=production - command: pnpm start - - -6. 本番デプロイ構成の補足 (Deployment Config) ------------------------------------------------------------------------- -本番環境へデプロイする際は,上記 `Dockerfile` をマルチステージビルドに修正し, -軽量化を図ることが推奨される. - -6-1. Dockerfile (本番用最適化例) - ※ 必要に応じて `Dockerfile.prod` として作成する. - - FROM node:20-slim AS base - ENV PNPM_HOME="/pnpm" - ENV PATH="$PNPM_HOME:$PATH" - RUN corepack enable - COPY . /app - WORKDIR /app - - FROM base AS prod-deps - RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile - - FROM base AS build - RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile - RUN pnpm run build - - FROM base - COPY --from=prod-deps /app/node_modules /app/node_modules - COPY --from=build /app/apps/server/dist /app/apps/server/dist - COPY --from=build /app/apps/client/dist /app/apps/client/dist - - EXPOSE 3000 - CMD [ "pnpm", "start" ] \ No newline at end of file diff --git "a/docs/01_Env/ENV_07_\343\203\206\343\202\271\343\203\210\346\223\215\344\275\234\346\211\213\351\240\206.txt" "b/docs/01_Env/ENV_07_\343\203\206\343\202\271\343\203\210\346\223\215\344\275\234\346\211\213\351\240\206.txt" deleted file mode 100644 index 9d943c7..0000000 --- "a/docs/01_Env/ENV_07_\343\203\206\343\202\271\343\203\210\346\223\215\344\275\234\346\211\213\351\240\206.txt" +++ /dev/null @@ -1,96 +0,0 @@ -======================================================================== -テスト操作手順 (Test Operation Guide) -======================================================================== - - -1. 概要 (Overview) ------------------------------------------------------------------------- -本ドキュメントは,プロジェクト内のテスト関連ファイルの実行方法を整理し,チーム内で共通の運用手順を共有することを目的とする. - - -1-1. 対象範囲 - -■ 対象ファイル -・テスト実行用スクリプト: /workspace/test/load-bot.mjs -・テスト用依存定義: /workspace/test/package.json - -■ 対象外 -・アプリ本体のビルドと起動手順 -・本番運用の監視設定 - - -2. 前提条件 (Prerequisites) ------------------------------------------------------------------------- - -2-1. 環境 -・Node.js / pnpm が利用可能であること -・インターネット接続が利用可能であること - -2-2. 設定値 -■ 接続先URL -・既定値: https://skillsemiwebgame.onrender.com -・変更方法: コマンドライン引数(--dev)または定数を編集する - - -3. 実行手順 (Execution Steps) ------------------------------------------------------------------------- - -3-1. 初回準備 -1. テスト用ディレクトリへ移動 - - コマンド: $ cd /workspace/test -2. 依存関係のインストール - - コマンド: $ pnpm install - -3-2. 実行 - - コマンド: $ pnpm start - - 開発環境に接続する場合: $ pnpm start -- --dev - - -4. パラメータ一覧 (Parameters) ------------------------------------------------------------------------- -4-1. コマンドライン引数 - ・--dev: 開発環境(DEV_SERVER_URL)に接続する - -4-2. 定数 (load-bot.constants.ts) - ・URL: 本番サーバURL - ・DEV_URL: 開発サーバURL - ・BOTS: 同時接続数 - ・DURATION_MS: 実行時間 (ms)。0以下またはInfinityで無期限 - ・JOIN_DELAY_MS: 参加間隔 (ms) - ・MOVE_TICK_MS: 移動送信間隔 (ms) - ・BOT_SPEED: 移動速度 - ・BOT_RADIUS: プレイヤー半径 - ・BOT_CAN_MOVE: ボット移動の有効化 (true/false) - ・START_DELAY_MS: 開始遅延 (ms) - ・MAX_X: X座標上限 - ・MAX_Y: Y座標上限 - ・ROOM_ID: ルームID - ・START_GAME: ゲーム開始の有効化 (true/false) - ・SOCKET_PATH: Socket.IOのパス - ・SOCKET_TRANSPORTS: Socket.IOのトランスポート - - -5. 出力と終了 (Output & Termination) ------------------------------------------------------------------------- - -5-1. 標準出力 - ・開始時に設定値が出力される - ・終了時に簡易統計 (接続数など) が出力される - -5-2. 終了方法 - ・指定時間経過後に自動終了する - ・途中終了する場合はプロセスを終了する - - -6. 注意事項 (Notes) ------------------------------------------------------------------------- - -6-1. 本番サーバへの負荷 - ・負荷テストは低負荷から段階的に実施すること - ・必要に応じて管理者へ事前連絡を行うこと - -6-2. 依存関係 - ・test配下は独立した依存関係を持つため,別途pnpm installが必要になる - -6-3. 計測の限界 - ・本スクリプトは簡易負荷確認用であり,詳細な計測は専用ツールの利用を推奨する diff --git "a/docs/01_Env/ENV_08_\347\240\224\347\251\266\345\256\244\343\202\265\343\203\274\343\203\220\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206\346\233\270.txt" "b/docs/01_Env/ENV_08_\347\240\224\347\251\266\345\256\244\343\202\265\343\203\274\343\203\220\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206\346\233\270.txt" deleted file mode 100644 index 6f4179d..0000000 --- "a/docs/01_Env/ENV_08_\347\240\224\347\251\266\345\256\244\343\202\265\343\203\274\343\203\220\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206\346\233\270.txt" +++ /dev/null @@ -1,279 +0,0 @@ -======================================================================== -研究室サーバデプロイ手順書 (Lab Server Deployment Guide) -======================================================================== - -1. 概要 (Overview) ------------------------------------------------------------------------- -本ドキュメントは,Pixel Paint War を1台の研究室サーバ上に本番デプロイする -手順をまとめたものである. -Nginx をリバースプロキシとして使用し,外部公開ポートは 8803 のみとする. -フロントエンド(静的ファイル)とバックエンド(Socket.IO)は同一サーバ内で -ポートを分けて動作させ,外部デバイスは Nginx 経由でのみ通信する. - - -1-1. 構成図 - - [デバイス] ──HTTP(8803)──▶ [Nginx (:8803)] - ├── / → 静的ファイル配信(Viteビルド済み) - └── /socket.io → proxy_pass http://127.0.0.1:3000 - (サーバ内部のみ,外部非公開) - - ・外部公開ポート: 8803 のみ - ・バックエンド(ポート3000)は localhost バインドで外部アクセス不可 - ・HTTPS化する場合は Nginx で SSL 終端を行う(6章参照) - - -2. 前提条件 (Prerequisites) ------------------------------------------------------------------------- - -2-1. サーバ環境 - ・OS: Linux(Ubuntu 20.04 以上推奨) - ・Docker / Docker Compose がインストール済みであること - ・Nginx がインストール済みであること - ・Git がインストール済みであること - ・ポート 8803 がファイアウォールで許可されていること - -2-2. 確認コマンド - $ docker --version - $ docker compose version - $ nginx -v - $ git --version - - -3. デプロイ手順 (Deployment Steps) ------------------------------------------------------------------------- - -3-1. リポジトリの取得 - 1. サーバ上で任意のディレクトリにクローンする - $ git clone <リポジトリURL> /opt/pixel-paint-war - $ cd /opt/pixel-paint-war - - 2. デプロイ対象のブランチ・タグに切り替える - $ git checkout main - $ git pull origin main - -3-2. フロントエンドのビルド - フロントエンドは静的ファイルとしてビルドし,Nginx から配信する. - VITE_PROD_SERVER_URL にはデバイスからアクセスする URL を指定する. - - ■ ローカルネットワーク(HTTP)の場合 - $ docker run --rm -v $(pwd):/app -w /app node:20-slim \ - bash -c "corepack enable && pnpm install --frozen-lockfile \ - && pnpm --filter @repo/shared build \ - && VITE_PROD_SERVER_URL=http://<サーバIP>:8803 pnpm --filter client build" - - ■ ドメイン運用(HTTPS)の場合 - $ docker run --rm -v $(pwd):/app -w /app node:20-slim \ - bash -c "corepack enable && pnpm install --frozen-lockfile \ - && pnpm --filter @repo/shared build \ - && VITE_PROD_SERVER_URL=https://yourdomain.example.com:8803 pnpm --filter client build" - - ※ ビルド成果物は apps/client/dist/ に出力される - -3-3. バックエンドの起動(Docker Compose) - 本番用の docker-compose.prod.yml を使用してバックエンドを起動する. - ポートは localhost バインドとし,Nginx 経由でのみアクセスさせる. - - 1. docker-compose.prod.yml を以下の内容に編集する - - services: - game-server: - build: - context: . - dockerfile: Dockerfile - container_name: pixel-paint-server-prod - restart: unless-stopped - ports: - - "127.0.0.1:3000:3000" - environment: - - NODE_ENV=production - - ※ ポイント: ports を "127.0.0.1:3000:3000" にすることで, - localhost からのみアクセス可能となり外部に直接公開されない - - 2. コンテナをビルド・起動する - $ docker compose -f docker-compose.prod.yml up -d --build - - 3. 起動確認 - $ docker compose -f docker-compose.prod.yml ps - - STATUS が「Up」になっていることを確認する - - 4. ヘルスチェック - $ curl http://127.0.0.1:3000 - - 「ok」と返れば正常 - -3-4. Nginx の設定 - Nginx の設定ファイルを作成し,ポート 8803 でリクエストを受け付ける. - - 1. 設定ファイルを作成する - $ sudo vi /etc/nginx/sites-available/pixel-paint-war - - 2. 以下の内容を記述する - - server { - listen 8803; - server_name _; - - # フロントエンド(静的ファイル配信) - root /opt/pixel-paint-war/apps/client/dist; - index index.html; - - location / { - try_files $uri $uri/ /index.html; - } - - # バックエンド(Socket.IO → 内部ポート3000へプロキシ) - location /socket.io/ { - proxy_pass http://127.0.0.1:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - } - - 3. シンボリックリンクを作成して有効化する - $ sudo ln -s /etc/nginx/sites-available/pixel-paint-war /etc/nginx/sites-enabled/ - - 4. 設定の文法チェック - $ sudo nginx -t - - 「syntax is ok」「test is successful」と表示されること - - 5. Nginx を再起動する - $ sudo systemctl restart nginx - -3-5. 動作確認 - 1. ブラウザからアクセスする - http://<サーバIP>:8803 - - 2. ゲーム画面が表示され,ルーム作成・参加が正常に動作することを確認する - - 3. バックエンドへの直接アクセスが遮断されていることを確認する - $ curl http://<サーバIP>:3000 - → 接続拒否またはタイムアウトになること - - -4. ファイアウォール設定 (Firewall) ------------------------------------------------------------------------- -外部に公開するポートを 8803 のみに制限する. - -4-1. ufw を使用する場合 - $ sudo ufw allow 8803/tcp - $ sudo ufw deny 3000/tcp - $ sudo ufw enable - $ sudo ufw status - -4-2. 確認事項 - ・ポート 8803: 外部からアクセス可能であること - ・ポート 3000: 外部からアクセス不可であること - ・SSH ポート(22): 許可済みであること(ロックアウト防止) - - -5. 運用コマンド (Operations) ------------------------------------------------------------------------- - -5-1. 基本操作 - ■ バックエンドの状態確認 - $ docker compose -f docker-compose.prod.yml ps - - ■ ログ確認(リアルタイム) - $ docker compose -f docker-compose.prod.yml logs -f - - ■ バックエンドの停止 - $ docker compose -f docker-compose.prod.yml down - - ■ バックエンドの再起動 - $ docker compose -f docker-compose.prod.yml restart - - ■ Nginx の状態確認 - $ sudo systemctl status nginx - -5-2. アップデート手順 - コードを更新して再デプロイする場合の手順. - - 1. 最新コードを取得する - $ cd /opt/pixel-paint-war - $ git pull origin main - - 2. フロントエンドを再ビルドする(3-2 の手順を再実行) - - 3. バックエンドを再ビルド・再起動する - $ docker compose -f docker-compose.prod.yml up -d --build - - 4. Nginx を再読み込みする(設定変更がある場合のみ) - $ sudo systemctl reload nginx - -5-3. キャッシュクリア再ビルド - ビルドキャッシュが原因で問題が発生する場合に実行する. - - $ docker compose -f docker-compose.prod.yml build --no-cache - $ docker compose -f docker-compose.prod.yml up -d --force-recreate - - -6. HTTPS化(任意) (HTTPS Setup) ------------------------------------------------------------------------- -ドメインを使用して HTTPS でアクセスさせる場合の追加手順. - -6-1. Let's Encrypt で証明書を取得する - $ sudo apt install certbot python3-certbot-nginx - $ sudo certbot --nginx -d yourdomain.example.com - -6-2. Nginx 設定を HTTPS 対応に変更する - - server { - listen 8803 ssl; - server_name yourdomain.example.com; - - ssl_certificate /etc/letsencrypt/live/yourdomain.example.com/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/yourdomain.example.com/privkey.pem; - - root /opt/pixel-paint-war/apps/client/dist; - index index.html; - - location / { - try_files $uri $uri/ /index.html; - } - - location /socket.io/ { - proxy_pass http://127.0.0.1:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - } - -6-3. 証明書の自動更新を確認する - $ sudo certbot renew --dry-run - - -7. トラブルシューティング (Troubleshooting) ------------------------------------------------------------------------- - -7-1. ブラウザでゲーム画面が表示されない - ・Nginx のエラーログを確認する - $ sudo tail -50 /var/log/nginx/error.log - ・静的ファイルのパスが正しいか確認する - $ ls /opt/pixel-paint-war/apps/client/dist/index.html - -7-2. Socket.IO 接続がエラーになる - ・バックエンドコンテナが起動しているか確認する - $ docker compose -f docker-compose.prod.yml ps - ・ローカルからバックエンドに疎通できるか確認する - $ curl http://127.0.0.1:3000 - ・Nginx のプロキシ設定で WebSocket ヘッダーが正しいか確認する - -7-3. ポート 8803 にアクセスできない - ・ファイアウォールでポート 8803 が許可されているか確認する - $ sudo ufw status - ・Nginx がポート 8803 で listen しているか確認する - $ sudo ss -tlnp | grep 8803 diff --git "a/docs/01_GUIDE/GUIDE_01_\343\203\211\343\202\255\343\203\245\343\203\241\343\203\263\343\203\210\344\275\234\346\210\220\343\202\254\343\202\244\343\203\211.txt" "b/docs/01_GUIDE/GUIDE_01_\343\203\211\343\202\255\343\203\245\343\203\241\343\203\263\343\203\210\344\275\234\346\210\220\343\202\254\343\202\244\343\203\211.txt" new file mode 100644 index 0000000..e4f637b --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_01_\343\203\211\343\202\255\343\203\245\343\203\241\343\203\263\343\203\210\344\275\234\346\210\220\343\202\254\343\202\244\343\203\211.txt" @@ -0,0 +1,121 @@ +======================================================================== +ドキュメント作成ガイドライン (Style Guide) +======================================================================== + +1. 基本フォーマット (Basic Format) +------------------------------------------------------------------------ +・文字コード: UTF-8 +・改行コード: LF (推奨) または CRLF +・インデント: 半角スペース4つ (4 spaces) + - タブ文字は使用せず、スペースに展開して揃える. +・ファイル命名: `GUIDE_02_ファイル命名規則.txt` を参照する. + +■ ファイルヘッダー (File Header) +・ファイルの先頭には必ずタイトルブロックを記述する. +・書式: 上下を「=」(イコール)の列(72文字程度)で挟む. +・例: + ======================================================================== + ドキュメントタイトル (English Title) + ======================================================================== + + +2. 句読点・約物 (Punctuation) +------------------------------------------------------------------------ +・句読点: 「,」(全角カンマ)と「.」(全角ピリオド)を使用する. + - 「、」「。」は使用しない. +・コロン: 半角コロン+半角スペース「: 」を使用する. + - NG: 全角コロン「:」,スペースなし「:」 +・括弧: 原則として半角括弧 `( )` を使用するが、強調や補足には全角 `( )` や `「 」` も許容する. +・注釈: 文末や段落末の補足には「※」(全角米印)+半角スペースを使用する. + - 例: ※ shared は client/server 両方から import して使用する. + + +3. 階層構造と見出し (Headings & Hierarchy) +------------------------------------------------------------------------ + +3-1. レベル1:大見出し (Section) + ・書式: 数字 + ドット + 半角スペース + タイトル + (英語タイトル) + ・装飾: 下行にハイフン「-」による区切り線を挿入する. + ・例: + 1. 基本設計 (Basic Design) + ------------------------------------------------------------------------ + +3-2. レベル2:中見出し (Subsection) + ・書式: 数字-数字 + ドット + 半角スペース + タイトル + ・例: + 1-1. 製品概要 + +3-3. レベル3:小見出し (Group Heading) + ・書式: 「■」+ 半角スペース + タイトル + ・使い分け: + - セクション内で独立したトピック(カテゴリ)を列挙する場合は「■」を使用する. + - 手順やフロー、順序のある項目を示す場合は「1. 」「2. 」を使用する. + + A. 並列・カテゴリ列挙(順序不問) + - 記号: 「■ 」(全角四角+半角スペース) + - 例: ■ フィールド仕様 + + B. 手順・優先順位・ランキング(順序重要) + - 記号: 「1. 」「2. 」(半角数字+ドット+半角スペース) + - 例: 1. ユーザ体験の理想 + +3-4. レベル4:リスト項目 (List Item) + ・記号: 「・」(全角中黒) + ・書式: 「・項目名: 内容」または「・項目名」のみ. + ・使いどころ: セクション内の主要な列挙(親項目)に使用する. + ・例: + ・タイトル: Paint War + +3-5. レベル5:詳細項目 (Detail Item) + ・記号: 「- 」(半角ハイフン+半角スペース) + ・インデント: 親項目のテキスト開始位置に合わせる(基本はスペース8つ). + ・使いどころ: 親が「・」のとき,その補足・条件・内訳を子項目として記述する. + ・ルール: 親が「・」なら子は必ず「- 」を使う. + ・例: + ・接続設定 + - host: localhost + - port: 3000 + +3-6. 特殊なナンバリング (Zero Indexing) + ・目的定義: セクションの冒頭で目的や定義を述べる場合、「X-0. 目的」というナンバリング(ゼロ始まり)を使用してもよい. + - 例: 1-0. 目的 + +3-7. 階層の順守 + ・上位レベルから下位レベルへ順に記述し,階層を飛ばさないこと. + - NG例: レベル1(1. XX)の直下にレベル3(■ XX)を記述する. + - 対策: 必要に応じてレベル2(1-1. 概要 等)を設ける. + + +4. 余白・改行ルール (Spacing) +------------------------------------------------------------------------ +・大見出しの上: 2行空ける. +・中見出し(X-X)の上: 1行空ける. +・小見出し(■や数字)の上: 1行空ける. +・セクション内のリスト: 原則として行間を詰め、まとまりごとに適宜空行を入れる. +・ミニサンプル: + 1. 基本設計 (Basic Design) + ------------------------------------------------------------------------ + + + 1-1. 製品概要 + + ■ 主要要件 + ・要件A: 説明 + ・要件B: 説明 + + ■ 補足 + ・注意点: 説明 + +・NG例(空行不足): + 1. 基本設計 (Basic Design) + ------------------------------------------------------------------------ + 1-1. 製品概要 + ■ 主要要件 + ・要件A: 説明 + + +5. 技術記述・コード表記 (Technical & Code) +------------------------------------------------------------------------ +・コマンドライン: 先頭に `$ ` を付与して区別する. +・ディレクトリ構造: ツリー記号(`├──`, `│`, `└──`)を使用し,ルートディレクトリからの階層を示す. +・インデント: コードブロック内は,親の箇条書きレベルに合わせて開始位置を揃える. \ No newline at end of file diff --git "a/docs/01_GUIDE/GUIDE_02_\343\203\225\343\202\241\343\202\244\343\203\253\345\221\275\345\220\215\350\246\217\345\211\207.txt" "b/docs/01_GUIDE/GUIDE_02_\343\203\225\343\202\241\343\202\244\343\203\253\345\221\275\345\220\215\350\246\217\345\211\207.txt" new file mode 100644 index 0000000..a8217e6 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_02_\343\203\225\343\202\241\343\202\244\343\203\253\345\221\275\345\220\215\350\246\217\345\211\207.txt" @@ -0,0 +1,54 @@ +======================================================================== +ドキュメント管理・ファイル命名規則 (File Naming Conventions) +======================================================================== + +1. 命名の基本方針 (Basic Policy) +------------------------------------------------------------------------ +プロジェクトの規模拡大に伴うファイルの散乱を防ぎ,開発メンバーおよびAI(Gemini/Copilot)がファイルの内容・文脈を即座に特定できるようにするため,以下の規則を適用する. +※ 書式・記述スタイルの基準は `GUIDE_01_ドキュメント作成ガイド.txt` を参照する. + +■ 基本フォーマット +`[カテゴリ]_[連番]_[ファイル名].txt` + +・区切り文字: アンダースコア `_` を使用する. +・連番: 01から始まる2桁の数字とする. +・拡張子: プレーンテキスト `.txt` とする. + + +2. カテゴリ定義 (Category Definitions) +------------------------------------------------------------------------ +ファイル名の先頭に付与するプレフィックス(接頭辞)定義. + +■ GUIDE_ (Guide) +・内容: チーム全体のルール,規約,運用フローなど,「メタ情報」に関する定義. +・対象例: スタイルガイド,命名規則,Git運用ルール. + +■ PLAN_ (Planning) +・内容: プロジェクトの進行計画,スケジュール,要件定義など,「管理・進行」に関する定義. +・対象例: WBS,ロードマップ,要件定義書,タスク一覧. + +■ ENV_ (Environment) +・内容: 開発環境,ディレクトリ構造,ライブラリ選定など,プロジェクトの「土台」に関する定義. +・対象例: 環境構築手順,技術スタック一覧,パッケージ構成図. + +■ SPEC_ (Specification) +・内容: 企画,ゲームルール,UI/UXなど,ユーザーから見える「仕様」に関する定義. +・対象例: ゲーム企画書,画面遷移図,パラメータ設定(マップサイズ・速度など). + +■ TECH_ (Technical) +・内容: 実装詳細,アルゴリズム,データ構造など,エンジニア向けの「技術設計」に関する定義. +・対象例: 通信プロトコル仕様,同期ロジック,データベース設計,クラス設計. + +■ TEST_ (Test) +・内容: テスト計画,テストケース,品質保証手順など,「検証・品質」に関する定義. +・対象例: 単体テスト仕様書,シナリオテスト計画,テストケース一覧,品質基準. + + +3. 運用ルール (Operational Rules) +------------------------------------------------------------------------ +・1ファイル1テーマ: + ファイルサイズが肥大化しすぎないよう,トピック(例: 通信仕様,判定ロジック)ごとにファイルを分割することを推奨する. + これにより,AIへのコンテキスト入力精度が向上する. + +・スタイルの継承: + 新規作成するファイルも,必ず `GUIDE_01_ドキュメント作成ガイド.txt` に記載された書式(見出し,句読点「,.」等)に従うこと. \ No newline at end of file diff --git "a/docs/01_GUIDE/GUIDE_03_Git\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.txt" "b/docs/01_GUIDE/GUIDE_03_Git\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.txt" new file mode 100644 index 0000000..2bff163 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_03_Git\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.txt" @@ -0,0 +1,127 @@ +======================================================================== +Git運用ルール (Git Operation Rules) +======================================================================== + +1. 基本方針 (Basic Policy) +------------------------------------------------------------------------ +チーム開発におけるコードの整合性を保ち,手戻りを防ぐために以下の運用フローを徹底する. + +・メインブランチ (main): + - 本番環境または常に動作可能な状態を維持するブランチ. + - 直接のコミット(直プッシュ)は禁止する.必ずプルリクエスト(PR)経由でマージする. +・作業ブランチ (Feature Branch): + - 機能追加やバグ修正ごとに `main` から派生させて作成する. + - 作業完了後,`main` へマージし,原則として削除する. + + +2. ブランチ命名規則 (Branch Naming) +------------------------------------------------------------------------ +2-1. プレフィックス (Prefix) +作業の種類を一目で判別するために,以下のプレフィックスを使用する. + +■ カテゴリ一覧 + ・feature/: 新機能の実装,仕様変更 + ・fix/: バグ修正 + ・refactor/: コードの整理(挙動は変えない) + ・docs/: ドキュメントの追記・修正 + ・chore/: ビルド設定やツール導入など,雑多な作業 + +2-2. 書式 (Format) + ・書式: `[プレフィックス][日付(YYMMDD)]_[名前]_[概要]` + ・区切り: スラッシュ `/` および アンダースコア `_` を使用する. + ・例: + - feature/260207_yamada_player_jump + - fix/260208_tanaka_collision_bug + - docs/260210_suzuki_guide_update + + +3. 開発フロー (Development Workflow) +------------------------------------------------------------------------ +作業を開始してからマージされるまでの手順. + +1. ローカルの最新化 + ・作業開始前は必ず `main` ブランチに切り替え,リモートの最新状態を取り込む. + ・コマンド: + $ git checkout main + $ git pull origin main + +2. 作業ブランチの作成 + ・最新の `main` から新しいブランチを作成して移動する. + ・コマンド: + $ git checkout -b feature/260214_yamada_new_function + +3. 実装とコミット + ・作業単位(意味のあるまとまり)ごとにコミットする. + ・巨大なコミットは避け,レビューしやすい粒度を心がける. + ・VS CodeでCopilotを使用している場合,AIによるコミットメッセージの生成機能(キラキラアイコン等)を利用してもよい. + ただし,生成されたメッセージは必ず「4. コミットメッセージ」の書式ルール(タグや日本語化)に合わせて修正すること. + ・コマンド: + $ git add . + $ git commit -m "[add] 新機能を実装" + +4. リモートへのプッシュ + ・作業ブランチをリモートリポジトリへ送信する. + ・コマンド: + $ git push origin feature/260214_yamada_new_function + +5. プルリクエスト (PR) の作成 + ・GitHubのリポジトリ画面上部に表示される「Compare & pull request」ボタンをクリックする. + ・Baseを `main`、Compareを自分の「作業ブランチ」に設定する. + ・「Reviewers」メニューからチームメンバーを選択し、レビューを依頼する. + ・「Create pull request」ボタンを押してPRをオープンする. + +6. レビューと修正の対応 + ・レビュワーのコメントを確認し、修正が必要な場合はローカルで修正・コミット・プッシュを繰り返す. + ・GitHub上で全ての指摘に対し「Resolve conversation」を行い、やり取りを完了させる. + ・レビュワーから「Approve(承認)」のスタンプまたはメッセージをもらう. + +7. マージの実行(マージボタンの操作) + ・PR画面下部の「Merge pull request」ボタンをクリックする. + ・確認用の「Confirm merge」ボタンを押し、`main` への統合を完了させる. + ・マージ直後に表示される「Delete branch」ボタンを押し、リモート上の作業ブランチを削除する. + +8. ローカル環境のクリーンアップ + ・マージ完了後はローカル環境も最新状態に戻し、古いブランチを削除する. + $ git checkout main + $ git pull origin main + $ git branch -d [作業ブランチ名] + + +4. コミットメッセージ (Commit Messages) +------------------------------------------------------------------------ +4-1. 書式 + ・書式: `[タグ] 内容` + ・言語: 日本語 (Japanese) + ・句読点: 末尾に句点は不要. + +4-2. タグ一覧 + ・[add]: ファイルや機能の追加 + ・[update]: 機能やデータの更新・修正 + ・[fix]: バグ修正 + ・[remove]: 削除 + ・[clean]: 整理,リファクタリング + + +5. トラブルシューティング (Troubleshooting) +------------------------------------------------------------------------ +■ コンフリクト (Conflict) が発生した場合 +他メンバーの変更と競合した場合の対処手順. + +1. main の取り込み + ・作業ブランチに `main` の最新内容をマージして競合箇所を洗い出す. + ・コマンド: + $ git checkout main + $ git pull origin main + $ git checkout feature/260214_yamada_new_function + $ git merge main + +2. 競合の解消 + ・エディタ上で `<<<<<<<`, `=======`, `>>>>>>>` で囲まれた箇所を手動で修正する. + ・修正後,再度コミットしてプッシュする. + +■ 間違えて main にコミットしてしまった場合 + ・まだプッシュしていない場合,コミットを取り消して新しいブランチへ移動させる. + ・コマンド: + $ git reset --soft HEAD^ + $ git checkout -b feature/260214_yamada_new_function + $ git commit -m "..." \ No newline at end of file diff --git "a/docs/01_GUIDE/GUIDE_04_\343\202\263\343\203\274\343\203\211\343\202\263\343\203\241\343\203\263\343\203\210\350\246\217\345\211\207.txt" "b/docs/01_GUIDE/GUIDE_04_\343\202\263\343\203\274\343\203\211\343\202\263\343\203\241\343\203\263\343\203\210\350\246\217\345\211\207.txt" new file mode 100644 index 0000000..2faa119 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_04_\343\202\263\343\203\274\343\203\211\343\202\263\343\203\241\343\203\263\343\203\210\350\246\217\345\211\207.txt" @@ -0,0 +1,124 @@ +======================================================================== +コードコメント・ドキュメント規則 (Code Comment & Documentation Guide) +======================================================================== + + +1. 基本方針 (Basic Policy) +------------------------------------------------------------------------ +コードの可読性と保守性を高めるため,ファイル・型・関数・定数それぞれに対して +適切な粒度でコメントを記述する. + +・言語: 日本語で記述する. +・句読点: 「,」(全角カンマ)を使用し,文末の句点(「.」「。」)は付けない + - 列挙が続く場合は「,」で区切る +・文体: 体言止め,または「〜する」形で統一する + + +2. コメントの種類と用途 (Comment Types) +------------------------------------------------------------------------ + +2-1. ファイルドキュメント (File Header Doc Comment) + ・ファイルの先頭に必ず記述する. + ・JSDoc形式(`/** */`)を使用する. + ・書式: + + /** + * [ファイル名(拡張子なし)] + * [ファイルの主な責務を1行で説明] + * [補足情報があれば続けて記述] + */ + + ・例: + + /** + * useJoystick + * ジョイスティック入力を受け取り,座標計算と正規化ベクトルの出力を行うフック + * UI描画に必要な中心点・ノブ位置・半径も合わせて提供する + */ + +2-2. 型・定数ドキュメント (Type & Constant Doc Comment) + ・`export` される型(`type`,`interface`)および定数(`const`)には必ず記述する. + ・JSDoc形式の1行コメント(`/** */`)を直前行に記述する. + ・書式: + + /** [その型・定数が何を表すかを端的に説明] */ + export type / const ... + + ・例: + + /** UI側と共有する最大半径の既定値 */ + export const MAX_DIST = 60; + + /** 2D座標の簡易型 */ + type Point = { x: number; y: number }; + + /** フックが返すUI向けの状態とハンドラ */ + type UseJoystickReturn = { ... }; + +2-3. 関数・コンポーネント・フックドキュメント (Function Doc Comment) + ・`export` される関数,Reactコンポーネント,フックには必ず記述する. + ・JSDoc形式の1行コメント(`/** */`)を直前行に記述する. + ・書式: + + /** [その関数・コンポーネントが何をするかを端的に説明] */ + export const / function ... + + ・例: + + /** 正規化ベクトルの出力とUI用の座標を提供するフック */ + export const useJoystick = ... + + /** ポインター入力と描画を結びつけるジョイスティックUI */ + export const Joystick = ... + +2-4. ブロックコメント (Block Comment) + ・関数・コンポーネント内で,処理のまとまりが変わる箇所に記述する. + ・通常の行コメント(`//`)を使用する. + ・書式: + + // [このブロックの処理を端的に説明] + ...処理... + + ・例: + + // 入力開始時の基準座標をセットする + const handleStart = ... + + // 入力座標からベクトルを計算し,半径でクランプして正規化出力する + const handleMove = ... + +2-5. JSXコメント (JSX Comment) + ・JSX内のブロック区切りには `{/* */}` 形式を使用する. + ・例: + + {/* 見た目のみの描画(入力は扱わない) */} + + +2-6. 再エクスポートコメント (Re-export Comment) + ・外部へ再公開する `export { ... }` には1行ドキュメントを付ける. + ・例: + + /** 入力半径の既定値を外部から参照できるように再公開 */ + export { MAX_DIST } from "./useJoystick"; + + +3. 記述しない場合の判断基準 (When to Omit) +------------------------------------------------------------------------ +・ファイル内部でのみ使用し,外部に公開されない型・関数・定数は省略してもよい +・コード自体が自明な場合(変数名で意図が十分伝わる場合)は省略してもよい +・ユニットテストファイルは,テストケース名で意図が伝わる場合は省略してもよい + + +4. NG例 (Anti-patterns) +------------------------------------------------------------------------ +・句点を付ける + - NG: /** ジョイスティックの入力を受け取る. */ + - OK: /** ジョイスティックの入力を受け取る */ + +・「、」「。」を使う + - NG: // 入力開始時の基準座標をセットする。 + - OK: // 入力開始時の基準座標をセットする + +・ファイルヘッダーを通常の行コメントで書く + - NG: // useJoystick: ジョイスティック入力を受け取るフック + - OK: /** \n * useJoystick\n * ジョイスティック入力を受け取るフック\n */ diff --git "a/docs/01_GUIDE/GUIDE_05_\343\203\227\343\203\255\343\203\210\343\202\263\343\203\253\350\277\275\345\212\240\346\211\213\351\240\206.txt" "b/docs/01_GUIDE/GUIDE_05_\343\203\227\343\203\255\343\203\210\343\202\263\343\203\253\350\277\275\345\212\240\346\211\213\351\240\206.txt" new file mode 100644 index 0000000..3104ac6 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_05_\343\203\227\343\203\255\343\203\210\343\202\263\343\203\253\350\277\275\345\212\240\346\211\213\351\240\206.txt" @@ -0,0 +1,111 @@ +======================================================================== +プロトコル追加手順 (Protocol Extension Guide) +======================================================================== + + +1. 目的 (Purpose) +------------------------------------------------------------------------ +本ドキュメントは,ソケットイベントの追加・変更時に,修正箇所の漏れを防ぐための標準手順を定義する. +`packages/shared/src/protocol` の責務分割方針に従い,イベント名,ペイロード型,方向別マップ,公開エントリを順に更新する. + + +2. 適用対象 (Scope) +------------------------------------------------------------------------ +・対象レイヤ: shared プロトコル定義(client/server 共通契約) +・対象ディレクトリ: `packages/shared/src/protocol` +・対象ユースケース: 新規イベント追加,既存イベントのペイロード変更,イベント廃止 + + +3. ディレクトリ構成 (Directory Layout) +------------------------------------------------------------------------ +・基準構成は以下とする. + + packages/shared/src/protocol/ + ├── socketEvents.ts + ├── eventPayloads.ts + ├── eventPayloadMaps.ts + ├── events.ts + ├── socketEventBridge.ts + ├── payloads/ + │ ├── commonPayloads.ts + │ ├── lobbyPayloads.ts + │ └── gamePayloads.ts + └── maps/ + ├── commonEventPayloadMap.ts + ├── lobbyEventPayloadMap.ts + └── gameEventPayloadMap.ts + + +4. 標準追加フロー (Standard Flow) +------------------------------------------------------------------------ +新規イベントを追加する場合は,必ず次の順で更新する. + +4-1. イベント名を追加する + ・ファイル: socketEvents.ts + ・作業: `SocketEvents` にイベント名を追加する + ・確認: 命名規則(kebab-case / snake_case)を既存方針に合わせる + +4-2. ペイロード型を追加する + ・ファイル: payloads/commonPayloads.ts または payloads/lobbyPayloads.ts または payloads/gamePayloads.ts + ・作業: イベントに対応する payload 型を追加する + ・確認: 既存型の再利用可否を確認し,重複定義を避ける + +4-3. 方向別マップへ対応を追加する + ・ファイル: maps/commonEventPayloadMap.ts / maps/lobbyEventPayloadMap.ts / maps/gameEventPayloadMap.ts + ・作業: 追加イベントを C→S または S→C の適切な map に追記する + ・確認: 方向が誤っていないかを必ず確認する + +4-4. 集約エントリの再公開を調整する + ・ファイル: eventPayloads.ts / eventPayloadMaps.ts / events.ts + ・作業: 外部利用が必要な型のみ再公開する + ・確認: 既存 import パス互換(`@repo/shared` 経由)を維持する + +4-5. 利用側を接続する + ・対象: client/server の handler / bridge / useCase + ・作業: on/off/emit と payload 型参照を更新する + + +5. 変更時のチェックポイント (Checklist) +------------------------------------------------------------------------ +・イベント名追加済みか +・payload 型追加済みか +・map への方向別登録済みか +・events.ts 再公開が過不足ないか +・client/server で型エラーがないか +・既存イベントの型互換を壊していないか +・player 座標差分イベント(SocketEvents.UPDATE_PLAYERS / update-players)に teamId を含めていないか +・初期同期イベント(SocketEvents.CURRENT_PLAYERS / current-players,SocketEvents.NEW_PLAYER / new-player)に teamId を含めているか + + +6. 典型ミスと対策 (Common Pitfalls) +------------------------------------------------------------------------ +■ イベント名だけ追加して map を更新しない +・症状: emit/on の型推論が崩れる,もしくは any 化する +・対策: 4-3 を必須工程として実施する + +■ payload 定義場所が不適切 +・症状: common/lobby/game の境界が曖昧になる +・対策: イベント責務に従って payloads 配下へ配置する + +■ 循環参照を作る +・症状: 型解決エラー,TS2307/TS2456 系が発生しやすくなる +・対策: `events.ts` は再公開専用とし,型本体は payload 側へ置く + + +7. 検証コマンド (Validation Commands) +------------------------------------------------------------------------ +・shared 型定義のビルド確認 + $ pnpm --filter @repo/shared build + +・サーバー互換確認 + $ pnpm --filter server build + +・クライアント互換確認 + $ pnpm --filter client build + + +8. 運用ルール (Operation Rules) +------------------------------------------------------------------------ +・プロトコル追加時は,本ガイドの 4-1 から 4-5 までを PR テンプレート上でチェックする +・events.ts に型本体を戻さない(再公開専用を維持する) +・新規型のコメントは `GUIDE_04_コードコメント規則` に従う diff --git "a/docs/02_ENV/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" "b/docs/02_ENV/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" new file mode 100644 index 0000000..5fbf76b --- /dev/null +++ "b/docs/02_ENV/ENV_01_\347\222\260\345\242\203\346\247\213\347\257\211\343\203\273\346\212\200\350\241\223\343\202\271\343\202\277\343\203\203\343\202\257.txt" @@ -0,0 +1,179 @@ +======================================================================== +Pixel Paint War - 開発環境・技術スタック定義書 +======================================================================== + +1. プロジェクト基本方針 +------------------------------------------------------------------------ + +1-1. アーキテクチャ構成: Monorepo (モノレポ) + ・目的: クライアント(Client)とサーバー(Server)で,言語(TypeScript)およびゲームロジック(移動演算・定数・型定義)を完全共有するため. + ・パッケージ管理: pnpm workspaces を採用. + +1-2. コア・コンセプト + ・言語: TypeScript (Strict mode) + ・通信: WebSocket (Socket.IO) + - 全イベントを JSON 形式で送受信(開発効率とデバッグ容易性を優先) + ・描画: WebGL 2D (Pixi.js) + ・同期: サーバー権限 (Authoritative) + クライアント予測 (Prediction) + +1-3. AI活用型開発 (AI-Assisted Development) + ・採用ツール: + - Gemini Pro (学校提供ライセンス) + - GitHub Copilot Pro (GitHub Student Developer Pack) + ・言語選定の優位性: + TypeScriptを採用することで厳密な型定義(Type/Interface)を保持する. + これによりAIがコードの文脈や意図を正確に解釈可能となり, + 型のないJavaScriptと比較して,コード生成・補完・リファクタリングの精度が著しく向上する. + + +2. プロジェクト構成 (Project Structure) +------------------------------------------------------------------------ + +2-1. 構成一覧 + root/ + ├── .devcontainer/ + │ └── devcontainer.json # 開発コンテナ設定 + ├── apps/ + │ ├── client/ # 【演出】フロントエンド (Browser) + │ │ ├── index.html # HTMLエントリ + │ │ ├── package.json # 依存・スクリプト + │ │ ├── public/ # 公開アセット (SVG・PNG等) + │ │ ├── src/ # ※ 詳細は ENV_02 参照 + │ │ ├── tsconfig.json # TS設定 + │ │ └── vite.config.ts # Vite設定 + │ └── server/ # 【権限】バックエンド (Node.js) + │ ├── package.json # 依存・スクリプト + │ ├── tsconfig.json # TS設定 + │ └── src/ # ※ 詳細は ENV_02 参照 + ├── packages/ + │ └── shared/ # 【最重要】「真実」の定義場所(型,定数,純粋ロジック) + │ ├── package.json # 依存・公開設定 + │ ├── tsconfig.json # TS設定 + │ └── src/ # ※ 詳細は ENV_02 参照 + ├── test/ # 負荷テスト用スクリプト群 + │ ├── load-bot.ts # 負荷テスト実行 + │ ├── load-bot.constants.ts # 負荷テスト定数 + │ ├── package.json # テスト依存・スクリプト + │ └── tsconfig.json # テストTS設定 + ├── docs/ # プロジェクトドキュメント + ├── .gitignore # Git除外設定 + ├── .npmrc # pnpm設定 + ├── docker-compose.yml # 開発Compose定義 + ├── docker-compose.prod.yml # 本番Compose定義 + ├── Dockerfile # 本番イメージ定義 + ├── package.json # ワークスペース定義 + ├── pnpm-lock.yaml # lockファイル + ├── pnpm-workspace.yaml # workspace設定 + ├── CLAUDE.md # Claude Code設定 + └── README.md # プロジェクト概要 + + ※ shared は client/server 両方から import して使用する. + ※ ソースコード (src/) の詳細構造は ENV_02_ディレクトリ構造.txt を参照. + + +3. 技術スタック詳細 (Tech Stack) +------------------------------------------------------------------------ + +3-1. 共通・基盤 (Common / Shared) + ・Runtime: Node.js (v20 LTS 以上) + ・Package Manager: pnpm + ・Build Tool: tsup (高速で軽量なTypeScriptバンドラ) + +3-2. フロントエンド (Client) + ・Build Tool: Vite + ・Language: TypeScript + ・Rendering Engine: Pixi.js (v8) + - 採用理由: 50人同時対戦時の大量のスプライト描画と60fps維持のため. + ・UI Library: React 18 + @pixi/react + - 採用理由: 充実したエコシステムとPixi.jsとのReact統合による効率的なUI構築のため. + ・Network: socket.io-client + +3-3. バックエンド (Server) + ・Runtime: Node.js + ・Execution: tsx (開発時の高速実行・ウォッチ用) + ・WebSocket Library: Socket.IO + - 採用理由: 接続管理・イベント配線を明確化しやすく,Client 側 (socket.io-client) と整合するため. + ・Logic: 独自ループ (20Hz固定) + - Physics Engine: 使用しない (shared/domains/game/gridMap/ による独自グリッド判定) + +3-4. 開発ツール (Dev Tools) + ・Linter: ESLint + ・Formatter: Prettier + ・AI Assistant: GitHub Copilot Pro, Gemini Pro + +3-5. インフラ・コンテナ技術 (Infrastructure) + ・Containerization: Docker + - 採用理由: 開発環境(Dev Containers)と本番環境の差異を排除するため. + ・Orchestration: + - Dev: Docker Compose (ボリュームマウントによるホットリロード) + - Prod: Docker Compose (再起動ポリシーとポート開放のみの最小構成) + ・Deployment Image: Multi-stage Build (Node.js Slim) + - ビルド戦略: + 1. Builderステージ: 全依存をインストールし,TypeScript (Shared -> Server) をコンパイル. + 2. Prune: `pnpm prune --prod` により開発依存を削除. + 3. Copy: pnpmの仕様(シンボリックリンク)に対応するため,`node_modules` を明示的にコピーする. + 4. Runnerステージ: 必要な `dist` と `node_modules` のみをコピーし,イメージサイズを最小化する. + + +4. 開発マシンの前提条件 (Prerequisites) +------------------------------------------------------------------------ +本プロジェクトは Docker (Dev Containers) による開発環境統一を推奨する. +これにより,ホストOS(Windows/Mac)の環境を汚さずに構築が可能となる. + +4-1. 【必須】ホストマシンにインストールするもの + 以下のツールのみ,開発者のPC(ホストOS)にインストールが必要である. + + 1. Docker実行環境 + - Docker Desktop (最新版) + - WSL2 (Windowsの場合必須) + + 2. エディタ + - VS Code (Visual Studio Code) + + 3. VS Code 拡張機能 + - Dev Containers (ID: ms-vscode-remote.remote-containers) + ※ これが「必須」である.これさえあれば,以下の開発ツール群は自動セットアップされる. + + 4. アカウント・AI + - GitHub Copilot Pro (Student) + - Gemini Pro (学校提供ライセンス) + +4-2. 【自動】コンテナ内に構築されるもの (インストール不要) + 以下のツールは `devcontainer.json` に定義済みであり,コンテナ起動時に + 自動的にインストール・設定されるため,手動導入は不要である. + + 1. Runtime & Package Manager + - Node.js (v20.x LTS) + - pnpm (Latest) + + 2. VS Code 拡張機能 (コンテナ内) + - ESLint + - Prettier + - EditorConfig + - Hex Editor + + ※ ホスト側で `node -v` や `pnpm -v` を実行する必要はなく, + 全て VS Code の「ターミナル (コンテナ接続済)」で行う. + + +5. 実装上の重要ルール (Implementation Rules) +------------------------------------------------------------------------ + +5-1. ロジックの一元管理 + - 「移動速度」「ヒット判定」「マップ更新」の計算式は必ず `packages/shared` に記述する. + - Client と Server で別の計算式を書くことを禁止する(同期ズレ防止). + +5-2. 座標系 + - 内部計算: Float (浮動小数点) + - 通信データ: Integer (整数 / 100倍して送信など圧縮を考慮) + - 描画: Float (補間処理あり) + +5-3. 依存方向 + - OK: Client -> Shared + - OK: Server -> Shared + - NG: Client -> Server / Server -> Client (直接参照禁止) + +5-4. 通信境界の責務分離 + - SocketEvents の解決(イベント名の参照)は `apps/server/src/network` 配下に集約する. + - `apps/server/src/domains` 配下では `protocol` を直接 import せず,意味名の Publisher 関数を受け取って利用する. + - Socket の接続制御・受信イベント登録・切断順序制御は network 層が担当し,業務ロジック判断は domain 層が担当する. diff --git "a/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\351\200\240.txt" "b/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\351\200\240.txt" new file mode 100644 index 0000000..972528f --- /dev/null +++ "b/docs/02_ENV/ENV_02_\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\346\247\213\351\200\240.txt" @@ -0,0 +1,235 @@ +======================================================================== +ソースコードディレクトリ構造 (Source Code Directory Structure) +======================================================================== + +1. 概要 (Overview) +------------------------------------------------------------------------ +本ドキュメントは apps/client/src,apps/server/src,packages/shared/src 配下の +ソースコード構造を定義する. +プロジェクト全体の構成(設定ファイル・インフラ)については ENV_01 を参照すること. + + +2. クライアント (apps/client/src) +------------------------------------------------------------------------ + +2-1. 構成一覧 + src/ + ├── app.tsx # ルートUI + ├── index.css # 全体スタイル + ├── main.tsx # 起動エントリ + ├── vite-env.d.ts # Vite型定義 + ├── assets/ # 画像素材 + ├── components/ + │ └── LandscapeOnlyGate.tsx # 横向き制御ゲート + ├── config/ + │ └── index.ts # クライアント設定 + ├── hooks/ + │ ├── useAppFlow.ts # 画面遷移フック + │ ├── useSocketSubscriptions.ts # WS購読フック + │ ├── application/ # アプリケーション層フック + │ └── types/ # フック型定義 + ├── network/ + │ ├── SocketManager.ts # WSクライアント + │ └── handlers/ + │ ├── CommonHandler.ts # 共通WSハンドラ + │ ├── GameHandler.ts # ゲームWSハンドラ + │ ├── GameSyncHandler.ts # ゲーム同期ハンドラ + │ ├── LobbyHandler.ts # ロビーWSハンドラ + │ ├── TitleHandler.ts # タイトルWSハンドラ + │ └── socketEventBridge.ts # イベントブリッジ + ├── styles/ + │ └── safeArea.ts # セーフエリア定義 + └── scenes/ + ├── game/ + │ ├── GameManager.ts # ゲーム制御 + │ ├── GameScene.tsx # ゲーム画面 + │ ├── GameView.tsx # ゲーム描画 + │ ├── application/ # ゲームアプリケーション層 + │ ├── entities/ + │ │ ├── bomb/ # 爆弾エンティティ + │ │ ├── hurricane/ # ハリケーンエンティティ + │ │ ├── map/ + │ │ │ ├── GameMapController.ts # マップ制御 + │ │ │ ├── GameMapModel.ts # マップモデル + │ │ │ └── GameMapView.ts # マップ描画 + │ │ └── player/ + │ │ ├── PlayerController.ts # プレイヤー制御 + │ │ ├── PlayerModel.ts # プレイヤーモデル + │ │ ├── PlayerRepository.ts # プレイヤーリポジトリ + │ │ └── PlayerView.ts # プレイヤー描画 + │ ├── hooks/ # ゲーム画面フック + │ ├── input/ + │ │ ├── GameInputOverlay.tsx # 入力オーバーレイ + │ │ ├── bomb/ # 爆弾ボタンUI + │ │ ├── hooks/ # 入力共通フック + │ │ ├── minimap/ # ミニマップUI + │ │ ├── joystick/ + │ │ │ ├── common/ # スティック定数・型 + │ │ │ ├── model/ # スティックモデル + │ │ │ ├── hooks/ # スティック制御フック + │ │ │ └── presentation/ # スティック描画 + │ │ └── presentation/ # 入力UI共通表示 + │ ├── presentation/ # ゲームHUD + │ └── styles/ # ゲーム画面スタイル + ├── lobby/ + │ ├── LobbyScene.tsx # ロビー画面 + │ ├── components/ # モーダル・設定UI + │ ├── presentation/ # ロビー表示ロジック + │ └── styles/ # ロビースタイル + ├── result/ + │ ├── ResultScene.tsx # 結果画面 + │ ├── components/ # ランキング・統計表示 + │ ├── hooks/ # 結果画面フック + │ ├── styles/ # 結果画面スタイル + │ └── types/ # 結果画面型定義 + ├── shared/ + │ └── styles/ # シーン共通スタイル + └── title/ + └── TitleScene.tsx # タイトル画面 + +2-2. 設計方針 + ・scenes/ 配下にシーン単位(title, lobby, game, result)で分割する + ・各シーンは MVC ベースの構成とし,entities/ に描画対象を集約する + ・network/ 層がサーバーとの通信を担当し,scenes/ 内から直接 protocol を参照しない + + +3. サーバー (apps/server/src) +------------------------------------------------------------------------ + +3-1. 構成一覧 + src/ + ├── index.ts # サーバー起点 + ├── application/ + │ └── coordinators/ # アプリ統合制御 + ├── common/ # 共通ユーティリティ + ├── config/ # サーバー設定 + ├── logging/ + │ ├── logger.ts # ログ出力 + │ ├── constants/ # ログ定数 + │ └── contracts/ # ログ契約型 + ├── domains/ + │ ├── game/ + │ │ ├── GameManager.ts # ゲーム状態管理 + │ │ ├── application/ + │ │ │ ├── ports/ + │ │ │ │ └── gameUseCasePorts.ts # ユースケース入出力境界 + │ │ │ ├── services/ + │ │ │ │ ├── GameSessionLifecycleService.ts # セッション管理 + │ │ │ │ ├── GamePlayerOperationService.ts # プレイヤー操作 + │ │ │ │ ├── GameRoomSession.ts # ルームセッション + │ │ │ │ ├── TeamAssignmentService.ts # チーム割当 + │ │ │ │ ├── currentPlayersBootstrapBuilder.ts # 初期プレイヤー構築 + │ │ │ │ ├── gameResultCalculator.ts # 結果算出 + │ │ │ │ └── bot/ # Bot AIシステム + │ │ │ └── useCases/ # ゲームユースケース + │ │ ├── entities/ + │ │ │ ├── bomb/ # 爆弾エンティティ + │ │ │ ├── map/ + │ │ │ │ └── MapStore.ts # マップ状態保持 + │ │ │ └── player/ + │ │ │ └── Player.ts # サーバーPlayer + │ │ └── loop/ + │ │ ├── GameLoop.ts # 固定ループ (20Hz) + │ │ ├── HurricaneSystem.ts # ハリケーン制御 + │ │ └── hurricane/ # ハリケーン詳細処理 + │ └── room/ + │ ├── RoomManager.ts # ルーム管理 + │ └── application/ + │ ├── ports/ + │ │ └── roomUseCasePorts.ts # ユースケース入出力境界 + │ ├── services/ # ルームサービス群 + │ └── useCases/ # ルームユースケース + └── network/ + ├── SocketManager.ts # WS接続管理 + ├── adapters/ + │ ├── socketEmitters.ts # 送信アダプタ + │ ├── gamePayloadSanitizers.ts # ゲームペイロード検証・整形 + │ └── realtimeRoomSyncState.ts # リアルタイムルーム同期状態 + ├── handlers/ + │ ├── CommonHandler.ts # 共通WSハンドラ + │ ├── connectionEventLogger.ts # 接続イベントログ + │ ├── createOutputAdapters.ts # 出力アダプタ生成 + │ ├── eventDefinitionRegistrar.ts # イベント定義登録 + │ ├── orchestratorEventLogger.ts # オーケストレータログ + │ ├── payloadGuard.ts # ペイロードガード + │ ├── registerConnectionHandlers.ts # 接続ハンドラ登録 + │ ├── socketEventBridge.ts # イベントブリッジ + │ ├── registration/ # 接続登録コンテキスト + │ ├── game/ + │ │ ├── registerGameHandlers.ts # ゲーム受信イベント配線 + │ │ ├── createGameOutputAdapter.ts # ゲーム出力アダプタ生成 + │ │ ├── gameEventOrchestrators.ts # ゲームイベントオーケストレータ + │ │ ├── aoi/ # 視認範囲フィルタ処理 + │ │ ├── runtime/ # ゲームランタイム解決 + │ │ └── services/ # ゲーム同期サービス群 + │ └── room/ + │ ├── registerRoomHandlers.ts # ルーム受信イベント配線 + │ ├── createRoomOutputAdapter.ts # ルーム出力アダプタ生成 + │ └── roomEventOrchestrators.ts # ルームイベントオーケストレータ + ├── bootstrap/ + │ ├── boot.ts # 起動配線 + │ ├── createHttpServer.ts # HTTP生成 + │ ├── createIo.ts # Socket.IO生成 + │ └── createServerRuntime.ts # ランタイム生成 + ├── types/ # ネットワーク型定義 + └── validation/ # ペイロード検証 + +3-2. 設計方針 + ・domains/ にビジネスロジックを集約し,game/ と room/ に分離する + ・network/ 層が Socket.IO の接続管理・イベント配線を担当する + ・domains/ は protocol を直接参照せず,ports/ 経由で network 層と連携する + ・loop/ 配下にサーバーティック(20Hz)とハリケーンシステムを配置する + + +4. 共有パッケージ (packages/shared/src) +------------------------------------------------------------------------ + +4-1. 構成一覧 + src/ + ├── index.ts # 共有エクスポート + ├── config/ + │ ├── index.ts # 設定エクスポート + │ ├── gameConfig.ts # 共通定数 + │ ├── networkConfig.ts # 通信設定 + │ └── teamValidators.ts # チーム検証 + ├── domains/ + │ ├── app/ + │ │ ├── app.const.ts # アプリ定数 + │ │ └── app.type.ts # アプリ型 + │ ├── game/ + │ │ ├── aoi/ # 視認範囲 (Area of Interest) + │ │ ├── bombHit/ # 爆弾判定ロジック・型 + │ │ ├── gridMap/ + │ │ │ ├── gridMap.logic.ts # マップ計算 + │ │ │ ├── gridMap.type.ts # マップ型定義 + │ │ │ └── groupedCellUpdates.ts # セル更新グループ化 + │ │ ├── player/ + │ │ │ ├── player.type.ts # プレイヤー型 + │ │ │ └── moveSync.ts # 移動同期ロジック + │ │ └── tick/ # ティックシステム + │ └── room/ + │ ├── room.const.ts # ルーム定数 + │ └── room.type.ts # ルーム型 + └── protocol/ + ├── socketEvents.ts # イベント名定義 + ├── eventPayloads.ts # ペイロード再公開 + ├── eventPayloadMaps.ts # 型マッピング + ├── socketEventBridge.ts # 型安全ブリッジ + ├── events.ts # イベント再公開 + ├── bombIdentity.ts # 爆弾一意性保証 + ├── payloads/ + │ ├── commonPayloads.ts # 共通ペイロード型 + │ ├── gamePayloads.ts # ゲームペイロード型 + │ ├── lobbyPayloads.ts # ロビーペイロード型 + │ └── playerHitEffectPayloads.ts # ヒットエフェクト型 + └── maps/ + ├── commonEventPayloadMap.ts # 共通イベントマップ + ├── gameEventPayloadMap.ts # ゲームイベントマップ + └── lobbyEventPayloadMap.ts # ロビーイベントマップ + +4-2. 設計方針 + ・client と server の両方から import される「真実の定義場所」として機能する + ・config/ にゲーム定数・通信設定を集約する + ・domains/ にドメインロジック(移動計算・マップ・判定)を配置する + ・protocol/ にソケットイベント定義・ペイロード型・型マッピングを一元管理する + ・protocol/events.ts は再公開専用とし,型本体を置かない(GUIDE_05 参照) diff --git "a/docs/02_ENV/ENV_03_\347\256\241\347\220\206\350\200\205\347\224\250\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" "b/docs/02_ENV/ENV_03_\347\256\241\347\220\206\350\200\205\347\224\250\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" new file mode 100644 index 0000000..3b39784 --- /dev/null +++ "b/docs/02_ENV/ENV_03_\347\256\241\347\220\206\350\200\205\347\224\250\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206.txt" @@ -0,0 +1,346 @@ +======================================================================== +Pixel Paint War - 管理者用環境構築手順 (Admin Setup Guide) +======================================================================== + +1. はじめに (Introduction) +------------------------------------------------------------------------ + 本ドキュメントは,プロジェクトを「ゼロから新規作成・再構築する管理者」向けの + Monorepo構成およびDocker環境の構築ログである. + ※ 一般の開発メンバー(Git Cloneして参加する人)は本ドキュメントを実施不要である. + +2. 管理者用事前準備 (Prerequisites for Admin) +------------------------------------------------------------------------ + +2-1. プロジェクト作成用ツールのインストール + 1. Node.js (v20.x LTS) + ・Nodesource リポジトリを使用してインストールする. + + # リポジトリのセットアップとインストール + $ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + $ sudo apt-get install -y nodejs + + ・確認コマンド: + $ node -v # v20.x.x と表示されること + + 2. pnpm (Package Manager) + ・Node.js 標準の npm ではなく pnpm を使用する. + ・Corepack (Node.js同梱) を有効化してインストールする. + $ sudo corepack enable + $ corepack prepare pnpm@latest --activate + + ・確認コマンド: + $ pnpm -v + + +3. 新規プロジェクト構築 (Project Initialization) +------------------------------------------------------------------------ + +3-1. プロジェクト初期化 + 1. ディレクトリ作成 + $ mkdir SkillSemiWebGame + $ cd SkillSemiWebGame + + 2. Git/pnpm 初期化 + $ git init + $ pnpm init + +3-2. Monorepo構成設定 + 1. pnpm-workspace.yaml 作成 + ルート直下に作成し、以下を記述する. + packages: + - 'apps/*' + - 'packages/*' + + 2. .npmrc 作成 + ルート直下に作成し、以下を記述する. + shamefully-hoist=true + +3-3. ディレクトリ構造の構築 + 以下の構成になるようにディレクトリを作成する. + + root/ + ├── apps/ + │ ├── client/ # フロントエンド (Browser) + │ └── server/ # バックエンド (Node.js) + └── packages/ + └── shared/ # 共通ロジック (Shared Library) + + ・作成コマンド例: + $ mkdir -p apps/client apps/server packages/shared + +3-4. Git除外設定 (.gitignore) + ルート直下に `.gitignore` を作成し、以下を記述する. + + node_modules/ + .pnpm-store/ + dist/ + build/ + .env + .DS_Store + .vscode/* + !.vscode/extensions.json + !.vscode/launch.json + coverage/ + !packages/ + + +4. アプリケーション雛形の作成 (Scaffolding) +------------------------------------------------------------------------ + +4-1. 共通ライブラリ (packages/shared) + 1. 初期化とビルドツール導入 + $ cd packages/shared + $ pnpm init + $ pnpm add -D typescript tsup + + 2. 設定ファイルの調整 (package.json) + ・name: "@repo/shared" と命名する(推奨). + ・main: "./dist/index.js", types: "./dist/index.d.ts" を指定する. + ・scripts: "build": "tsup src/index.ts --format cjs,esm --dts" を追加する. + + 3. エントリーポイントの作成 + $ mkdir src + $ touch src/index.ts + ※ (例: export * from './constants';) + + 4. TypeScript設定ファイルの作成 (tsconfig.json) + ・ファイル: packages/shared/tsconfig.json + ・内容: + { + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] + } + +4-2. フロントエンド (apps/client) + 1. プロジェクト作成 + $ cd ../../apps/client + $ pnpm create vite . --template preact-ts + ※ Use rolldown-vite? » No + ※ Install with pnpm and start now? » No + + 2. 依存ライブラリのインストール + $ pnpm add pixi.js + $ pnpm add @repo/shared --workspace + +4-3. バックエンド (apps/server) + 1. 初期化 + $ cd ../../apps/server + $ pnpm init + + 2. 依存ライブラリのインストール + $ pnpm add ws + $ pnpm add -D tsx typescript @types/node @types/ws + $ pnpm add @repo/shared --workspace + + 3. サーバー用ディレクトリとファイルの作成 + $ mkdir src + $ touch src/index.ts + + 4. 実行スクリプトの定義 (package.json) + "scripts": { + "dev": "tsx watch src/index.ts" + } + + 5. TypeScript設定ファイルの作成 (tsconfig.json) + ・ファイル: apps/server/tsconfig.json + ・内容: + { + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": ["ES2022"], + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "paths": { + "@repo/shared": ["../../packages/shared/src/index.ts"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] + } + +4-4. 初回コミット (Initial Commit) + 1. ルートに戻る + $ cd ../.. + 2. ステータスの確認 (node_modulesが含まれていないこと) + $ git status + 3. Gitへ保存 + $ git add . + $ git commit -m "chore: Initialize project structure and dependencies" + + +5. Docker環境定義ファイルの作成 (Configuration) +------------------------------------------------------------------------ + +5-1. Dockerfile の作成 + プロジェクトルートに `Dockerfile` を作成する. + ※ Node.js v20 をベースとし,pnpm を有効化した開発用イメージ定義. + + FROM node:20-slim + + # pnpmの準備 + ENV PNPM_HOME="/pnpm" + ENV PATH="$PNPM_HOME:$PATH" + RUN corepack enable + + # 作業ディレクトリ設定 + WORKDIR /workspace + + # 依存関係のコピーとインストール (キャッシュ活用) + COPY . . + RUN pnpm install + + # ポート公開 (Vite:5173, Server:3000) + EXPOSE 5173 3000 + + # デフォルトコマンド (docker-composeで上書きするため待機) + CMD ["sleep", "infinity"] + +5-2. docker-compose.yml の作成 (開発用) + プロジェクトルートに `docker-compose.yml` を作成する. + ※ ローカルのソースコードをコンテナにマウントする設定. + + version: "3.8" + + services: + app: + container_name: pixel-paint-war-dev + # 開発用イメージ: Node.js v20 (定義書準拠) + image: mcr.microsoft.com/devcontainers/typescript-node:20 + + # 永続化とボリュームマウント + volumes: + # カレントディレクトリをコンテナ内の /workspace にマウント + - .:/workspace:cached + # 【重要】node_modules をホスト側と切り離して高速化・安定化させる設定 + - node_modules:/workspace/node_modules + + # コマンドの上書き (コンテナを常時起動させる) + command: sleep infinity + + # ネットワーク設定 + # Client(5173) と Server(3000) のポートを開放 + ports: + - "5173:5173" + - "3000:3000" + + # 環境変数 + environment: + - NODE_ENV=development + + # ユーザー権限 (Nodeイメージ推奨のユーザー) + user: node + + volumes: + node_modules: + +5-3. .devcontainer 設定の作成 + 1. ディレクトリ作成 + $ mkdir .devcontainer + + 2. .devcontainer/devcontainer.json 作成 + VS Codeがコンテナを認識するための設定. + + { + "name": "Pixel Paint War Dev", + "dockerComposeFile": "../docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspace", + + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "20", + "pnpm": "latest" + } + }, + + "customizations": { + "vscode": { + "extensions": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "editorconfig.editorconfig", + "ms-vscode.hexeditor", + "github.copilot", + "github.copilot-chat" + ], + "settings": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" + } + } + }, + + // コンテナ起動後の初期化コマンド + // 1. sudo chown ... : node_modules の所有権を node ユーザーに強制変更 + // 2. pnpm install : その後,安全にインストールを実行 + // 3. build : 最後に共通パッケージをビルド + "postCreateCommand": "sudo chown -R node:node /workspace/node_modules && pnpm install && pnpm --filter @repo/shared build", + + // コンテナ内のユーザー + "remoteUser": "node" + } + +5-4. docker-compose.prod.yml の作成 (本番確認用) + プロジェクトルートに `docker-compose.prod.yml` を作成する. + ※ 本番ビルド確認用にポートをずらし、ビルドコマンドを実行する設定. + + services: + app: + build: . + ports: + - "3001:3000" + environment: + - NODE_ENV=production + command: pnpm start + + +6. 本番デプロイ構成の補足 (Deployment Config) +------------------------------------------------------------------------ +本番環境へデプロイする際は,上記 `Dockerfile` をマルチステージビルドに修正し, +軽量化を図ることが推奨される. + +6-1. Dockerfile (本番用最適化例) + ※ 必要に応じて `Dockerfile.prod` として作成する. + + FROM node:20-slim AS base + ENV PNPM_HOME="/pnpm" + ENV PATH="$PNPM_HOME:$PATH" + RUN corepack enable + COPY . /app + WORKDIR /app + + FROM base AS prod-deps + RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile + + FROM base AS build + RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile + RUN pnpm run build + + FROM base + COPY --from=prod-deps /app/node_modules /app/node_modules + COPY --from=build /app/apps/server/dist /app/apps/server/dist + COPY --from=build /app/apps/client/dist /app/apps/client/dist + + EXPOSE 3000 + CMD [ "pnpm", "start" ] \ No newline at end of file diff --git "a/docs/02_ENV/ENV_04_\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206\346\233\270.txt" "b/docs/02_ENV/ENV_04_\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206\346\233\270.txt" new file mode 100644 index 0000000..eb01c3b --- /dev/null +++ "b/docs/02_ENV/ENV_04_\347\222\260\345\242\203\346\247\213\347\257\211\346\211\213\351\240\206\346\233\270.txt" @@ -0,0 +1,246 @@ +======================================================================== +Pixel Paint War - 開発環境利用ガイド (Development Environment Guide) +======================================================================== + +1. 事前準備 (Prerequisites) +------------------------------------------------------------------------ + +1-1. 目的 + 本ドキュメントは,「Pixel Paint War」の開発に参加する全メンバー向けの + 環境構築および利用ガイドである. + Monorepo構成とDocker(Dev Containers)を使用し,迅速に開発を開始する手順を記す. + +1-2. 【全員必須】 共通ツールのインストール + 開発メンバー全員(管理者・参加者問わず)が以下のツールをインストールする. + + 1. Docker Engine (Linux環境) + ・開発環境の実体(コンテナ)を動かすために必須である. + + ・インストール手順 (Ubuntu/Debian系の例): + ターミナルで以下のコマンドを順に実行する. + + # 1. 公式GPG鍵とリポジトリのセットアップ + sudo apt-get update + sudo apt-get install -y ca-certificates curl gnupg + sudo install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg + sudo chmod a+r /etc/apt/keyrings/docker.gpg + + echo \ + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ + "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + + # 2. パッケージのインストール + sudo apt-get update + sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + + # 3. ユーザー権限の設定 (重要: VS Codeからsudoなしで利用するために必須) + sudo usermod -aG docker $USER + newgrp docker + + ・確認コマンド: + $ docker -v + # Docker version 20.x.x 等と表示されること + + 2. VS Code (Visual Studio Code) + ・メインのエディタとして使用する.最新版をインストールすること. + + 3. VS Code 拡張機能: "Dev Containers" + ・ID: ms-vscode-remote.remote-containers + ・拡張機能マーケットプレイスで検索し、インストールする. + ・これを入れることで、Dockerコンテナ内でVS Codeを開くことが可能になる. + + +2. 環境セットアップ (Setup) +------------------------------------------------------------------------ + + ■ リポジトリのクローン + 1. ソースコードの取得 + 任意のディレクトリで以下のコマンドを実行する. + $ git clone + + 2. ディレクトリ移動 + $ cd SkillSemiWebGame + + 3. 完了 + これだけで準備は完了である. + パッケージのインストール等はDocker起動時に自動で行われるため、 + 手動での `pnpm install` 等は不要である. + + +3. 開発環境(Dev Container)の起動 (Launch) +------------------------------------------------------------------------ + +3-1. プロジェクトを開く + 1. VS Codeを起動し,「ファイル > フォルダを開く」からプロジェクトルートを選択する. + +3-2. コンテナでの再起動 (Reopen in Container) + 以下のいずれかの方法で,開発環境をコンテナ内に移行する. + + 【方法A: ステータスバーから】 + 1. ウィンドウ左下の緑色(または青色)の「><」アイコンをクリックする. + 2. 表示されるメニューから「Reopen in Container」を選択する. + + 【方法B: コマンドパレットから】 + 1. [F1] または [Ctrl+Shift+P] を押下する. + 2. "Reopen" と入力し,「Dev Containers: Reopen in Container」を選択する. + + ※ トラブルシューティング: + もし起動後に node_modules が見つからない等のエラーが出た場合は, + 「Reopen」ではなく「Dev Containers: Rebuild Container」を選択して + 環境を完全に作り直してください. + +3-3. 初回ビルドの待機 + 1. 初回起動時は Dockerイメージのビルドと npmパッケージのインストールが行われる. + (数分〜十数分かかる場合がある) + 2. 右下に "Starting Dev Container" 等の通知が表示されている間は待機する. + +3-4. 起動確認 + 1. 左下のアイコンが「Dev Container: Pixel Paint War Dev」と表示されていることを確認する. + 2. VS Codeのターミナルを開き (`Ctrl + @`),パスを確認する. + + 成功例: node@...:/workspace$ + (Windowsのパス C:\Users... ではなく Linux形式になっていれば成功) + + 3. 動作確認コマンドを実行する. + $ pnpm --filter client dev + + ※ エラー時の対応: + 「sh: vite: not found」等のエラーが出る場合は,自動インストールが完了していない可能性があります. + ターミナルで `pnpm install` を手動実行するか,上記 3-2 の「Rebuild Container」を試してください. + + ・ブラウザでの確認: + ターミナルに「➜ Local: http://localhost:5173/」と表示されたら, + Google Chrome等のブラウザを開き,アドレスバーに上記URLを貼り付けて実行する. + + ・正常動作の判断基準: + 画面に「Vite + Preact」のロゴと「Vite + Preact + TypeScript」といった + テキストが表示されていれば,フロントエンドの環境構築は成功である. + + +4. 開発ツールの確認 (Tools Verification) +------------------------------------------------------------------------ +Dockerコンテナ起動完了後、定義済みのツールが正しく自動導入されているか確認する. +※ 手動でのインストールは不要である. + +4-1. VS Code 拡張機能 + 拡張機能サイドバーを開き、"Dev Container: Pixel Paint War Dev" セクションに + 以下がインストール済みであることを確認する. + ・ESLint + ・Prettier - Code formatter + ・EditorConfig for VS Code + ・Hex Editor + ・GitHub Copilot + +4-2. AI アシスタント設定 + GitHub Copilot Pro + - VS Code 右下のアイコンから、GitHubアカウントへのログイン状態を確認する. + + +5. 構成確認 (Project Structure) +------------------------------------------------------------------------ + +5-1. ディレクトリ構成 + コンテナ内で以下のディレクトリ構造が見えていることを確認する. + + SkillSemiWebGame/ <-- プロジェクトルート + ├── .devcontainer/ <-- Docker設定 + ├── .git/ + ├── docker-compose.yml <-- Docker構成 + ├── package.json <-- ルート定義 + ├── pnpm-workspace.yaml <-- ワークスペース定義 + ├── node_modules/ <-- 依存ライブラリ + │ + ├── apps/ <-- アプリケーション格納用 + │ ├── client/ <-- フロントエンド (Vite + Preact) + │ │ ├── src/ + │ │ │ ├── main.tsx + │ │ │ └── ... + │ │ ├── package.json <-- pixi.js, @repo/shared 依存あり + │ │ └── vite.config.ts + │ │ + │ └── server/ <-- バックエンド (Node.js) + │ ├── src/ + │ │ └── index.ts <-- エントリーポイント + │ └── package.json <-- ws, @repo/shared 依存あり + │ + └── packages/ <-- 共通パッケージ格納用 + └── shared/ <-- 共通ロジック + ├── dist/ <-- ビルド成果物 + ├── src/ + │ └── index.ts + └── package.json + +6. 動作確認 (Verification) +------------------------------------------------------------------------ + +6-1. ビルド確認 + ※ 注意: 以下のコマンドは全て「Dev Container内のターミナル」で実行すること. + + $ pnpm --filter @repo/shared build + ※ shared のビルドが成功することを確認する. + +6-2. 開発サーバー起動 + モノレポ構成のため,個別のディレクトリに移動せず,プロジェクトルートから + --filter オプションを使用して各アプリを起動する. + ※ ターミナルを2つ開き,両方を同時に起動した状態で開発を進めることを推奨. + + 1.Client (フロントエンド) の動作確認 + ・ルートディレクトリにて以下のコマンドを実行する. + $ pnpm --filter client dev + + ・ブラウザでの確認: + ターミナルに「➜ Local: http://localhost:5173/」と表示されたら, + Google Chrome等のブラウザを開き,アドレスバーに上記URLを貼り付けて実行する. + + ・正常動作の判断基準: + 画面に「Vite + Preact」のロゴと「Vite + Preact + TypeScript」といった + テキストが表示されていれば,フロントエンドの環境構築は成功である. + + 2. Server (バックエンド) の動作確認 + ・テスト用コードの作成: + 動作確認用のエントリーポイントを作成する. + $ touch apps/server/src/index.ts + + ファイルに以下の内容を記述する. + console.log("Server is running!"); + + ・コマンド: + $ pnpm --filter server dev + + ・正常動作の判断基準: + ターミナルに「Server is running!」と出力されれば構築成功である. + + 3.終了方法 (重要) + ・動作確認を終了し,開発サーバーを停止させる場合は,ターミナル上で + 「Ctrl + C」を押下する. + + +7. (応用) 本番ビルドの動作確認 (Production Build Check) +------------------------------------------------------------------------ +開発環境(Dev Container)ではなく,本番環境と同様のDockerイメージを作成し, +正しくビルド・起動できるかを確認する手順である. +「機能開発が終わった後」や「プルリクエストを出す前」に実施することを推奨する. + +7-1. 準備 + Dev Containerを閉じ,ホストOS(Windows/Mac)のターミナルを開く. + ※ Dev Container内からはDockerコマンドが使用できない場合があるため. + +7-2. ビルドと起動 + プロジェクトルートで以下のコマンドを実行する. + + $ docker compose -f docker-compose.prod.yml up -d --build + +7-3. 動作確認 + 1. ログ確認 + $ docker compose -f docker-compose.prod.yml logs -f + Serverが起動していることを確認する. + + 2. ブラウザ確認 + http://localhost:3001 + ※ ポート番号が開発用(3000/5173)と異なり 3001 に設定されている点に注意. + +7-4. 終了と削除 + 確認が終わったら必ず環境を停止・削除する. + $ docker compose -f docker-compose.prod.yml down \ No newline at end of file diff --git "a/docs/02_ENV/ENV_05_Docker\351\201\213\347\224\250\346\223\215\344\275\234\343\202\254\343\202\244\343\203\211.txt" "b/docs/02_ENV/ENV_05_Docker\351\201\213\347\224\250\346\223\215\344\275\234\343\202\254\343\202\244\343\203\211.txt" new file mode 100644 index 0000000..be89f13 --- /dev/null +++ "b/docs/02_ENV/ENV_05_Docker\351\201\213\347\224\250\346\223\215\344\275\234\343\202\254\343\202\244\343\203\211.txt" @@ -0,0 +1,82 @@ +======================================================================== +Docker 運用・操作ガイド (Docker Operations Guide) +======================================================================== + +1. 目的 (Objective) +------------------------------------------------------------------------ +本ドキュメントは,Pixel Paint War プロジェクトにおける Docker の日常的な +操作コマンドと,トラブルシューティング手順をまとめたものである. +本プロジェクトでは「開発環境」と「本番環境」で異なる運用を行う. + + +2. 開発環境 (Development Environment) +------------------------------------------------------------------------ +VS Code の Dev Containers 機能を使用する. + +2-1. +基本操作 + ・起動: VS Code でプロジェクトを開き,「Reopen in Container」を実行する. + ・停止: VS Code を閉じる(自動的に停止する). + ・ターミナル: VS Code 内のターミナルを使用する. + +2-2. +コンテナの再構築 (Rebuild) + 依存関係の不整合や設定変更が反映されない場合に実行する. + 1. コマンドパレット (F1) を開く. + 2. 「Dev Containers: Rebuild Container」を選択する. + 3. キャッシュを無視したい場合は「Rebuild Without Cache」を選択する. + + +3. 本番環境 (Production Environment) +------------------------------------------------------------------------ +手動で Docker Compose コマンドを実行する. +※ 必ず WSL (Windows) または ホストOSのターミナルで実行すること. + +3-1. +基本コマンド + ■ 起動 (ビルド込み) + $ docker compose -f docker-compose.prod.yml up -d --build + + ■ 状態確認 + $ docker compose -f docker-compose.prod.yml ps + + ■ ログ確認 (リアルタイム) + $ docker compose -f docker-compose.prod.yml logs -f + + ■ 停止 + $ docker compose -f docker-compose.prod.yml down + +3-2. +ポート仕様 + ・ホスト側ポート: 3001 + ・コンテナ内ポート: 3000 + ・接続確認URL: http://localhost:3001 + ※ 開発用コンテナ (Port 3000) との衝突を避けるため,3001番を使用する. + + +4. トラブルシューティング (Troubleshooting) +------------------------------------------------------------------------ + +4-1. +ビルドエラー・反映漏れへの対処 + 修正したコードが反映されない,または原因不明のエラーが出る場合, + キャッシュを使わずに強制的に再ビルドを行う. + + $ docker compose -f docker-compose.prod.yml build --no-cache + $ docker compose -f docker-compose.prod.yml up -d --force-recreate + +4-2. +モジュールが見つからない (MODULE_NOT_FOUND) + 本番起動時に `ws` 等が見つからないエラーが出る場合,`Dockerfile` の + COPY記述を確認する.pnpm のシンボリックリンク構造に対応するため, + 以下が記述されている必要がある. + + COPY --from=builder /app/apps/server/node_modules ./apps/server/node_modules + +4-3. +再起動ループ (Restarting) + `docker ps` でステータスが `Restarting` になる場合,サーバープロセスが + クラッシュまたは終了している. + 1. ログを確認する: + $ docker compose -f docker-compose.prod.yml logs --tail=50 + 2. コード修正後,4-1 の手順で再デプロイする. \ No newline at end of file diff --git "a/docs/02_ENV/ENV_06_\343\203\206\343\202\271\343\203\210\346\223\215\344\275\234\346\211\213\351\240\206.txt" "b/docs/02_ENV/ENV_06_\343\203\206\343\202\271\343\203\210\346\223\215\344\275\234\346\211\213\351\240\206.txt" new file mode 100644 index 0000000..d35d0ac --- /dev/null +++ "b/docs/02_ENV/ENV_06_\343\203\206\343\202\271\343\203\210\346\223\215\344\275\234\346\211\213\351\240\206.txt" @@ -0,0 +1,106 @@ +======================================================================== +テスト操作手順 (Test Operation Guide) +======================================================================== + + +1. 概要 (Overview) +------------------------------------------------------------------------ +本ドキュメントは,プロジェクト内のテスト関連ファイルの実行方法を整理し,チーム内で共通の運用手順を共有することを目的とする. + + +1-1. 対象範囲 + +■ 対象ファイル +・テスト実行用スクリプト: /workspace/test/load-bot.ts +・テスト用依存定義: /workspace/test/package.json + +■ 対象外 +・アプリ本体のビルドと起動手順 +・本番運用の監視設定 + + +2. 前提条件 (Prerequisites) +------------------------------------------------------------------------ + +2-1. 環境 +・Node.js / pnpm が利用可能であること +・インターネット接続が利用可能であること + +2-2. 設定値 +■ 接続先URL +・既定値: http://localhost:3000 +・変更方法: 環境変数(.env.local)またはコマンドライン引数(--dev)で切り替える + - LOAD_TEST_SERVER_URL: 本番接続先URL + - LOAD_TEST_DEV_SERVER_URL: 開発接続先URL + + +3. 実行手順 (Execution Steps) +------------------------------------------------------------------------ + +3-1. 初回準備 +1. テスト用ディレクトリへ移動 + - コマンド: $ cd /workspace/test +2. 依存関係のインストール + - コマンド: $ pnpm install + +3-2. 実行 + - コマンド: $ pnpm start + - 開発環境に接続する場合: $ pnpm start -- --dev + + +4. パラメータ一覧 (Parameters) +------------------------------------------------------------------------ +4-1. コマンドライン引数 + ・--dev: 開発環境(DEV_SERVER_URL)に接続する + +4-2. 定数 (load-bot.constants.ts) + ■ 接続設定 + ・URL: 本番サーバURL(環境変数 LOAD_TEST_SERVER_URL で上書き可能,既定: http://localhost:3000) + ・DEV_URL: 開発サーバURL(環境変数 LOAD_TEST_DEV_SERVER_URL で上書き可能,既定: http://localhost:3000) + ・SOCKET_PATH: Socket.IOのパス(shared の NETWORK_CONFIG から取得) + ・SOCKET_TRANSPORTS: Socket.IOのトランスポート(["websocket", "polling"]) + + ■ テスト実行設定 + ・BOTS: 同時接続するBot数(既定: 99) + ・DURATION_MS: テスト実行時間 (ms)(既定: Infinity = 無期限) + ・JOIN_DELAY_MS: Bot参加の間隔 (ms)(既定: 25) + ・START_DELAY_MS: 接続からゲーム開始リクエストまでの遅延 (ms)(既定: 800) + ・ROOM_ID: 参加するルームID(既定: "1") + ・START_GAME: 1体目のBotがゲーム開始を実行するか (true/false) + + ■ Bot動作設定 + ・BOT_CAN_MOVE: ボット移動の有効化 (true/false) + ・BOT_CAN_PLACE_BOMB: ボム設置の有効化 (true/false) + ・MOVE_TICK_MS: 移動送信間隔 (ms)(shared の GAME_CONFIG から取得) + ・BOT_SPEED: 移動速度(shared の GAME_CONFIG から取得) + ・BOT_RADIUS: プレイヤー半径(shared の GAME_CONFIG から取得) + ・BOMB_COOLDOWN_MS: ボムのクールダウン (ms)(shared の GAME_CONFIG から取得) + ・BOMB_FUSE_MS: ボムの爆発までの時間 (ms)(shared の GAME_CONFIG から取得) + ・MAX_X: X座標上限(shared の GAME_CONFIG.GRID_COLS) + ・MAX_Y: Y座標上限(shared の GAME_CONFIG.GRID_ROWS) + + +5. 出力と終了 (Output & Termination) +------------------------------------------------------------------------ + +5-1. 標準出力 + ・開始時に設定値が出力される + ・終了時に簡易統計 (接続数など) が出力される + +5-2. 終了方法 + ・指定時間経過後に自動終了する + ・途中終了する場合はプロセスを終了する + + +6. 注意事項 (Notes) +------------------------------------------------------------------------ + +6-1. 本番サーバへの負荷 + ・負荷テストは低負荷から段階的に実施すること + ・必要に応じて管理者へ事前連絡を行うこと + +6-2. 依存関係 + ・test配下は独立した依存関係を持つため,別途pnpm installが必要になる + +6-3. 計測の限界 + ・本スクリプトは簡易負荷確認用であり,詳細な計測は専用ツールの利用を推奨する diff --git "a/docs/02_ENV/ENV_07_\343\202\271\343\203\236\343\203\233\345\256\237\346\251\237\343\203\207\343\203\220\343\203\203\343\202\260\346\211\213\351\240\206.txt" "b/docs/02_ENV/ENV_07_\343\202\271\343\203\236\343\203\233\345\256\237\346\251\237\343\203\207\343\203\220\343\203\203\343\202\260\346\211\213\351\240\206.txt" new file mode 100644 index 0000000..06c1f56 --- /dev/null +++ "b/docs/02_ENV/ENV_07_\343\202\271\343\203\236\343\203\233\345\256\237\346\251\237\343\203\207\343\203\220\343\203\203\343\202\260\346\211\213\351\240\206.txt" @@ -0,0 +1,122 @@ +======================================================================== +スマホ実機デバッグ手順 (Smartphone Debugging Guide) +======================================================================== + + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-0. 目的 + 本ドキュメントは,開発中のWebゲーム「Pixel Paint War」をスマホ実機で動作 + 確認するための手順書である. + 学校や組織のネットワーク(Fortinet等)による制限や,WSL2特有のネットワー + クの壁を回避するため,トンネリングツール「ngrok」を使用した外部公開手順 + を採用する. + +1-1. 前提条件 + ・WSL2 (Ubuntu等) 上で開発環境が構築済みであること. + ・ngrok の公式サイトでアカウント作成済みであること. + ・Authtoken (認証トークン) が取得済みであること. + + +2. ngrokのインストール (Installation) +------------------------------------------------------------------------ +Linux (WSL2) 環境へのインストール手順を記述する. +※ apt パッケージマネージャ経由ではエラーが発生しやすいため,バイナリ直接 +インストール方式を採用する. + +2-1. ダウンロードと配置 + 1. 圧縮ファイルのダウンロード + ターミナルで以下のコマンドを実行し,Linux版バイナリを取得する. + $ wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz + + 2. 解凍とインストール + ダウンロードしたファイルを解凍し,実行パスの通ったディレクトリに移動する. + $ sudo tar xvzf ngrok-v3-stable-linux-amd64.tgz -C /usr/local/bin + + 3. 動作確認 + バージョン情報が表示されるか確認する. + $ ngrok --version + ※ "ngrok version 3.x.x" 等と表示されれば成功である. + +2-2. アカウント認証 (Authentication) + ngrok のダッシュボード (https://dashboard.ngrok.com/get-started/your-authtoken) + からトークンを確認し,以下のコマンドで設定する. + + ■ トークンの登録 + $ ngrok config add-authtoken [あなたのAuthtoken] + ※ "[あなたのAuthtoken]" の部分は実際の文字列に置き換える. + + +3. デバッグ実行手順 (Execution Steps) +------------------------------------------------------------------------ + +3-1. Client設定の修正 (Update Configuration) + 開発サーバーが外部 (ngrok) からの接続を受け付けるよう,設定を変更する. + + ■ package.json の編集 + `apps/client/package.json` を開き,`scripts` ブロックの `dev` コマンドに `--host` オプションを追加する. + + [修正前] + "dev": "vite" + + [修正後] + "dev": "vite --host" + +3-2. 開発サーバーの起動 (Launch Dev Server) + まず,ローカル環境でアプリケーションを起動する. + + ■ Clientアプリの起動 + プロジェクトルートで以下のコマンドを実行する. + $ pnpm --filter client dev + ※ ターミナルに `Network: http://x.x.x.x:5173/` と表示されれば設定成功である. + +3-3. ngrokによる公開 (Expose via ngrok) + 新しいターミナルウィンドウを開き,以下の手順でトンネルを作成する. + + 1. ngrokの起動 + Vite の Host ヘッダーチェックを回避するため,オプションを付与して実行する. + $ ngrok http 5173 --host-header="localhost" + + 2. 公開URLの確認 + 起動後に表示されるステータス画面から,"Forwarding" の行を確認する. + + Session Status online + Account User Name (Plan: Free) + Forwarding https://xxxx-xxxx.ngrok-free.app -> http://localhost:5173 + + 上記の "https://xxxx-xxxx.ngrok-free.app" が公開URLとなる. + +3-4. スマホからのアクセス (Access from Smartphone) + 1. URLの共有 + 発行された URL をスマホに送信する(QRコード作成ツールやチャット等を使用). + + 2. ブラウザでの確認 + スマホのブラウザ(Chrome,Safari等)で URL にアクセスする. + タイトル画面が表示されれば接続成功である. + + +4. 注意事項とトラブルシューティング (Notes & Troubleshooting) +------------------------------------------------------------------------ + +4-1. Freeプランの制限 + ・同時接続数: Freeプランでは同時に1つのポートしか公開できない. + ・Client/Server構成の注意: + 本手順ではフロントエンド (Port 5173) のみ公開している. + バックエンド (Port 3000) への WebSocket 通信が必要な場合,ゲーム開始時 + に接続エラーとなる可能性がある. + - 対策: UIレイアウトや描画負荷の確認を主目的として使用する. + +4-2. エラー対応 + ■ "ERR_NGROK_3200" (Tunnel already open) + ・既に別のターミナルで ngrok が起動している場合に発生する. + - 対策: 起動中の ngrok を終了 (Ctrl + C) してから再実行する. + + ■ "Invalid Host Header" (画面が真っ白になる) + ・Vite が不正なドメインからのアクセスを拒否している. + - 対策: 起動コマンドに `--host-header="localhost"` が含まれているか再確認する. + + ■ "ERR_CERT_AUTHORITY_INVALID" (Fortinet等の警告) + ・ngrok を使用せずローカルIPで接続しようとした場合に,組織内ネットワーク + のセキュリティ機器にブロックされる現象である. + - 対策: 必ず本手順の ngrok 経由 (https) で接続する. \ No newline at end of file diff --git "a/docs/02_ENV/ENV_08_\347\240\224\347\251\266\345\256\244\343\202\265\343\203\274\343\203\220\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206\346\233\270.txt" "b/docs/02_ENV/ENV_08_\347\240\224\347\251\266\345\256\244\343\202\265\343\203\274\343\203\220\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206\346\233\270.txt" new file mode 100644 index 0000000..6f4179d --- /dev/null +++ "b/docs/02_ENV/ENV_08_\347\240\224\347\251\266\345\256\244\343\202\265\343\203\274\343\203\220\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206\346\233\270.txt" @@ -0,0 +1,279 @@ +======================================================================== +研究室サーバデプロイ手順書 (Lab Server Deployment Guide) +======================================================================== + +1. 概要 (Overview) +------------------------------------------------------------------------ +本ドキュメントは,Pixel Paint War を1台の研究室サーバ上に本番デプロイする +手順をまとめたものである. +Nginx をリバースプロキシとして使用し,外部公開ポートは 8803 のみとする. +フロントエンド(静的ファイル)とバックエンド(Socket.IO)は同一サーバ内で +ポートを分けて動作させ,外部デバイスは Nginx 経由でのみ通信する. + + +1-1. 構成図 + + [デバイス] ──HTTP(8803)──▶ [Nginx (:8803)] + ├── / → 静的ファイル配信(Viteビルド済み) + └── /socket.io → proxy_pass http://127.0.0.1:3000 + (サーバ内部のみ,外部非公開) + + ・外部公開ポート: 8803 のみ + ・バックエンド(ポート3000)は localhost バインドで外部アクセス不可 + ・HTTPS化する場合は Nginx で SSL 終端を行う(6章参照) + + +2. 前提条件 (Prerequisites) +------------------------------------------------------------------------ + +2-1. サーバ環境 + ・OS: Linux(Ubuntu 20.04 以上推奨) + ・Docker / Docker Compose がインストール済みであること + ・Nginx がインストール済みであること + ・Git がインストール済みであること + ・ポート 8803 がファイアウォールで許可されていること + +2-2. 確認コマンド + $ docker --version + $ docker compose version + $ nginx -v + $ git --version + + +3. デプロイ手順 (Deployment Steps) +------------------------------------------------------------------------ + +3-1. リポジトリの取得 + 1. サーバ上で任意のディレクトリにクローンする + $ git clone <リポジトリURL> /opt/pixel-paint-war + $ cd /opt/pixel-paint-war + + 2. デプロイ対象のブランチ・タグに切り替える + $ git checkout main + $ git pull origin main + +3-2. フロントエンドのビルド + フロントエンドは静的ファイルとしてビルドし,Nginx から配信する. + VITE_PROD_SERVER_URL にはデバイスからアクセスする URL を指定する. + + ■ ローカルネットワーク(HTTP)の場合 + $ docker run --rm -v $(pwd):/app -w /app node:20-slim \ + bash -c "corepack enable && pnpm install --frozen-lockfile \ + && pnpm --filter @repo/shared build \ + && VITE_PROD_SERVER_URL=http://<サーバIP>:8803 pnpm --filter client build" + + ■ ドメイン運用(HTTPS)の場合 + $ docker run --rm -v $(pwd):/app -w /app node:20-slim \ + bash -c "corepack enable && pnpm install --frozen-lockfile \ + && pnpm --filter @repo/shared build \ + && VITE_PROD_SERVER_URL=https://yourdomain.example.com:8803 pnpm --filter client build" + + ※ ビルド成果物は apps/client/dist/ に出力される + +3-3. バックエンドの起動(Docker Compose) + 本番用の docker-compose.prod.yml を使用してバックエンドを起動する. + ポートは localhost バインドとし,Nginx 経由でのみアクセスさせる. + + 1. docker-compose.prod.yml を以下の内容に編集する + + services: + game-server: + build: + context: . + dockerfile: Dockerfile + container_name: pixel-paint-server-prod + restart: unless-stopped + ports: + - "127.0.0.1:3000:3000" + environment: + - NODE_ENV=production + + ※ ポイント: ports を "127.0.0.1:3000:3000" にすることで, + localhost からのみアクセス可能となり外部に直接公開されない + + 2. コンテナをビルド・起動する + $ docker compose -f docker-compose.prod.yml up -d --build + + 3. 起動確認 + $ docker compose -f docker-compose.prod.yml ps + + STATUS が「Up」になっていることを確認する + + 4. ヘルスチェック + $ curl http://127.0.0.1:3000 + + 「ok」と返れば正常 + +3-4. Nginx の設定 + Nginx の設定ファイルを作成し,ポート 8803 でリクエストを受け付ける. + + 1. 設定ファイルを作成する + $ sudo vi /etc/nginx/sites-available/pixel-paint-war + + 2. 以下の内容を記述する + + server { + listen 8803; + server_name _; + + # フロントエンド(静的ファイル配信) + root /opt/pixel-paint-war/apps/client/dist; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + # バックエンド(Socket.IO → 内部ポート3000へプロキシ) + location /socket.io/ { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } + + 3. シンボリックリンクを作成して有効化する + $ sudo ln -s /etc/nginx/sites-available/pixel-paint-war /etc/nginx/sites-enabled/ + + 4. 設定の文法チェック + $ sudo nginx -t + + 「syntax is ok」「test is successful」と表示されること + + 5. Nginx を再起動する + $ sudo systemctl restart nginx + +3-5. 動作確認 + 1. ブラウザからアクセスする + http://<サーバIP>:8803 + + 2. ゲーム画面が表示され,ルーム作成・参加が正常に動作することを確認する + + 3. バックエンドへの直接アクセスが遮断されていることを確認する + $ curl http://<サーバIP>:3000 + → 接続拒否またはタイムアウトになること + + +4. ファイアウォール設定 (Firewall) +------------------------------------------------------------------------ +外部に公開するポートを 8803 のみに制限する. + +4-1. ufw を使用する場合 + $ sudo ufw allow 8803/tcp + $ sudo ufw deny 3000/tcp + $ sudo ufw enable + $ sudo ufw status + +4-2. 確認事項 + ・ポート 8803: 外部からアクセス可能であること + ・ポート 3000: 外部からアクセス不可であること + ・SSH ポート(22): 許可済みであること(ロックアウト防止) + + +5. 運用コマンド (Operations) +------------------------------------------------------------------------ + +5-1. 基本操作 + ■ バックエンドの状態確認 + $ docker compose -f docker-compose.prod.yml ps + + ■ ログ確認(リアルタイム) + $ docker compose -f docker-compose.prod.yml logs -f + + ■ バックエンドの停止 + $ docker compose -f docker-compose.prod.yml down + + ■ バックエンドの再起動 + $ docker compose -f docker-compose.prod.yml restart + + ■ Nginx の状態確認 + $ sudo systemctl status nginx + +5-2. アップデート手順 + コードを更新して再デプロイする場合の手順. + + 1. 最新コードを取得する + $ cd /opt/pixel-paint-war + $ git pull origin main + + 2. フロントエンドを再ビルドする(3-2 の手順を再実行) + + 3. バックエンドを再ビルド・再起動する + $ docker compose -f docker-compose.prod.yml up -d --build + + 4. Nginx を再読み込みする(設定変更がある場合のみ) + $ sudo systemctl reload nginx + +5-3. キャッシュクリア再ビルド + ビルドキャッシュが原因で問題が発生する場合に実行する. + + $ docker compose -f docker-compose.prod.yml build --no-cache + $ docker compose -f docker-compose.prod.yml up -d --force-recreate + + +6. HTTPS化(任意) (HTTPS Setup) +------------------------------------------------------------------------ +ドメインを使用して HTTPS でアクセスさせる場合の追加手順. + +6-1. Let's Encrypt で証明書を取得する + $ sudo apt install certbot python3-certbot-nginx + $ sudo certbot --nginx -d yourdomain.example.com + +6-2. Nginx 設定を HTTPS 対応に変更する + + server { + listen 8803 ssl; + server_name yourdomain.example.com; + + ssl_certificate /etc/letsencrypt/live/yourdomain.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/yourdomain.example.com/privkey.pem; + + root /opt/pixel-paint-war/apps/client/dist; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location /socket.io/ { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } + +6-3. 証明書の自動更新を確認する + $ sudo certbot renew --dry-run + + +7. トラブルシューティング (Troubleshooting) +------------------------------------------------------------------------ + +7-1. ブラウザでゲーム画面が表示されない + ・Nginx のエラーログを確認する + $ sudo tail -50 /var/log/nginx/error.log + ・静的ファイルのパスが正しいか確認する + $ ls /opt/pixel-paint-war/apps/client/dist/index.html + +7-2. Socket.IO 接続がエラーになる + ・バックエンドコンテナが起動しているか確認する + $ docker compose -f docker-compose.prod.yml ps + ・ローカルからバックエンドに疎通できるか確認する + $ curl http://127.0.0.1:3000 + ・Nginx のプロキシ設定で WebSocket ヘッダーが正しいか確認する + +7-3. ポート 8803 にアクセスできない + ・ファイアウォールでポート 8803 が許可されているか確認する + $ sudo ufw status + ・Nginx がポート 8803 で listen しているか確認する + $ sudo ss -tlnp | grep 8803 diff --git "a/docs/02_ENV/ENV_09_TypeScript\346\246\202\350\246\201.txt" "b/docs/02_ENV/ENV_09_TypeScript\346\246\202\350\246\201.txt" new file mode 100644 index 0000000..e489c79 --- /dev/null +++ "b/docs/02_ENV/ENV_09_TypeScript\346\246\202\350\246\201.txt" @@ -0,0 +1,90 @@ +======================================================================== +TypeScript概要 (TypeScript Overview) +======================================================================== + +1. 概要 (Overview) +------------------------------------------------------------------------ +本プロジェクト(Pixel Paint War)において採用するプログラミング言語「TypeScript」に関する基礎知識,選定理由,およびAI活用開発における優位性を定義する. +本ドキュメントは,開発チーム内での技術認識の統一を目的とする. + + +2. TypeScriptとは (What is TypeScript) +------------------------------------------------------------------------ +Microsoftによって開発されたオープンソースのプログラミング言語である.JavaScriptのスーパーセット(上位互換)として設計されており,大規模なアプリケーション開発に適した機能が拡張されている. + +2-1. JavaScriptとの違い + ・静的型付け (Static Typing): + 変数や関数の引数,戻り値に「型(Type)」を指定できる.JavaScriptは動的型付け言語であり,実行時まで型が決まらないが,TypeScriptはコンパイル(トランスパイル)時に整合性をチェックする. + ・クラスベースオブジェクト指向: + インターフェース(Interface),ジェネリクス(Generics),アクセス修飾子(public/private)など,JavaやC#に近いオブジェクト指向構文をサポートする. + ・コンパイルの必要性: + ブラウザやNode.jsはTypeScriptを直接実行できないため,JavaScriptファイルへ変換(トランスパイル)して使用する. + +2-2. 一般的な利用目的 + ・大規模Webアプリケーション開発: + コード量が増えても型定義により保守性を維持しやすい. + ・チーム開発: + 型定義がそのまま「仕様書」としての役割を果たし,メンバー間の認識齟齬を防ぐ. + ・フルスタック開発: + フロントエンド(React/Vue/Angular等)とバックエンド(Node.js/Deno等)で言語を統一し,型定義を共有する. + + +3. 言語の強み (Strengths) +------------------------------------------------------------------------ + +3-1. 安全性と品質向上 + ・コンパイルエラーによる早期発見: + 「undefinedのプロパティ参照」や「数値と文字列の誤った演算」など,JavaScriptで頻発する実行時エラーを,コードを書いている段階(コンパイル時)で検出できる. + +3-2. 開発効率の向上 + ・強力な入力補完 (IntelliSense): + VS Code等のエディタにおいて,型情報を元にした正確なコード補完,メソッドの候補表示,定義元へのジャンプが可能となる. + ・リファクタリングの容易さ: + 変数名や関数名の変更を行っても,依存する箇所をエディタが一括で修正・検知できるため,改修コストが低い. + + +4. AI活用型開発における利点 (Benefits in AI-Assisted Development) +------------------------------------------------------------------------ +本プロジェクトの方針である「AI活用型開発(Gemini Pro / GitHub Copilot Pro)」において,TypeScriptはJavaScriptと比較して以下の決定的な優位性を持つ. + +■ コンテキストの正確な伝達 + 型定義(Type/Interface)が存在することで,AIは変数の意図やデータ構造を推測ではなく「確定情報」として認識できる.これにより,提案されるコードの精度が向上する. + +■ ハルシネーション(嘘の生成)の抑制 + 存在しないプロパティや誤ったメソッドをAIが提案した場合でも,TypeScriptのコンパイラが即座にエラーを出すため,誤ったコードが実装に含まれるリスクを自動的に排除できる. + +■ 意図の明示化 + 「ENV_01」で定義された `packages/shared` のような共通型定義を参照させることで,AIはクライアント・サーバー間の通信仕様を正確に理解し,一貫性のあるロジックを生成可能となる. + + +5. 歴史と現状 (History and Current Status) +------------------------------------------------------------------------ + +5-1. 歴史 + ・開発者: Anders Hejlsberg(C#やTurbo Pascalの設計者)らが中心となり開発. + ・初版公開: 2012年10月. + ・背景: 当時,大規模化するWebアプリ開発においてJavaScriptの仕様(ES5)では保守が困難であったため,静的型付けの需要が高まっていた. + +5-2. 現在のステータス + ・世界No.1の使用率 (GitHub Octoverse 2025): + 2025年のGitHub年次レポートにおいて,長年トップであったPythonおよびJavaScriptを上回り,世界で最も使用されている言語(第1位)となった. + このランキングは,単なるコードの総量ではなく「貢献者数(Unique Contributors)」に基づいており,現在世界中で最も多くのアクティブユーザーが開発を行っている言語であることを示している. + ・デファクトスタンダード: + 現在,モダンなフロントエンド開発(React, Next.js, Vue.jsなど)において,TypeScriptは標準的な選択肢となっている. + ・普及率: + 「State of JS」などの開発者アンケートにおいて,長年「使用率」および「満足度」で上位を維持している.また,Google社内の標準言語としても採用されている(Alligator等). + + +6. 参考文献 (References) +------------------------------------------------------------------------ +・TypeScript Official Website + https://www.typescriptlang.org/ + +・The State of JS 2022/2023 (Usage & Satisfaction) + https://stateofjs.com/ + +・GitHub Octoverse 2025 + https://octoverse.github.com/ + +・Google Engineering Practices Documentation + https://google.github.io/eng-practices/ \ No newline at end of file diff --git "a/docs/02_Guide/GUIDE_01_\343\203\211\343\202\255\343\203\245\343\203\241\343\203\263\343\203\210\344\275\234\346\210\220\343\202\254\343\202\244\343\203\211.txt" "b/docs/02_Guide/GUIDE_01_\343\203\211\343\202\255\343\203\245\343\203\241\343\203\263\343\203\210\344\275\234\346\210\220\343\202\254\343\202\244\343\203\211.txt" deleted file mode 100644 index e4f637b..0000000 --- "a/docs/02_Guide/GUIDE_01_\343\203\211\343\202\255\343\203\245\343\203\241\343\203\263\343\203\210\344\275\234\346\210\220\343\202\254\343\202\244\343\203\211.txt" +++ /dev/null @@ -1,121 +0,0 @@ -======================================================================== -ドキュメント作成ガイドライン (Style Guide) -======================================================================== - -1. 基本フォーマット (Basic Format) ------------------------------------------------------------------------- -・文字コード: UTF-8 -・改行コード: LF (推奨) または CRLF -・インデント: 半角スペース4つ (4 spaces) - - タブ文字は使用せず、スペースに展開して揃える. -・ファイル命名: `GUIDE_02_ファイル命名規則.txt` を参照する. - -■ ファイルヘッダー (File Header) -・ファイルの先頭には必ずタイトルブロックを記述する. -・書式: 上下を「=」(イコール)の列(72文字程度)で挟む. -・例: - ======================================================================== - ドキュメントタイトル (English Title) - ======================================================================== - - -2. 句読点・約物 (Punctuation) ------------------------------------------------------------------------- -・句読点: 「,」(全角カンマ)と「.」(全角ピリオド)を使用する. - - 「、」「。」は使用しない. -・コロン: 半角コロン+半角スペース「: 」を使用する. - - NG: 全角コロン「:」,スペースなし「:」 -・括弧: 原則として半角括弧 `( )` を使用するが、強調や補足には全角 `( )` や `「 」` も許容する. -・注釈: 文末や段落末の補足には「※」(全角米印)+半角スペースを使用する. - - 例: ※ shared は client/server 両方から import して使用する. - - -3. 階層構造と見出し (Headings & Hierarchy) ------------------------------------------------------------------------- - -3-1. レベル1:大見出し (Section) - ・書式: 数字 + ドット + 半角スペース + タイトル + (英語タイトル) - ・装飾: 下行にハイフン「-」による区切り線を挿入する. - ・例: - 1. 基本設計 (Basic Design) - ------------------------------------------------------------------------ - -3-2. レベル2:中見出し (Subsection) - ・書式: 数字-数字 + ドット + 半角スペース + タイトル - ・例: - 1-1. 製品概要 - -3-3. レベル3:小見出し (Group Heading) - ・書式: 「■」+ 半角スペース + タイトル - ・使い分け: - - セクション内で独立したトピック(カテゴリ)を列挙する場合は「■」を使用する. - - 手順やフロー、順序のある項目を示す場合は「1. 」「2. 」を使用する. - - A. 並列・カテゴリ列挙(順序不問) - - 記号: 「■ 」(全角四角+半角スペース) - - 例: ■ フィールド仕様 - - B. 手順・優先順位・ランキング(順序重要) - - 記号: 「1. 」「2. 」(半角数字+ドット+半角スペース) - - 例: 1. ユーザ体験の理想 - -3-4. レベル4:リスト項目 (List Item) - ・記号: 「・」(全角中黒) - ・書式: 「・項目名: 内容」または「・項目名」のみ. - ・使いどころ: セクション内の主要な列挙(親項目)に使用する. - ・例: - ・タイトル: Paint War - -3-5. レベル5:詳細項目 (Detail Item) - ・記号: 「- 」(半角ハイフン+半角スペース) - ・インデント: 親項目のテキスト開始位置に合わせる(基本はスペース8つ). - ・使いどころ: 親が「・」のとき,その補足・条件・内訳を子項目として記述する. - ・ルール: 親が「・」なら子は必ず「- 」を使う. - ・例: - ・接続設定 - - host: localhost - - port: 3000 - -3-6. 特殊なナンバリング (Zero Indexing) - ・目的定義: セクションの冒頭で目的や定義を述べる場合、「X-0. 目的」というナンバリング(ゼロ始まり)を使用してもよい. - - 例: 1-0. 目的 - -3-7. 階層の順守 - ・上位レベルから下位レベルへ順に記述し,階層を飛ばさないこと. - - NG例: レベル1(1. XX)の直下にレベル3(■ XX)を記述する. - - 対策: 必要に応じてレベル2(1-1. 概要 等)を設ける. - - -4. 余白・改行ルール (Spacing) ------------------------------------------------------------------------- -・大見出しの上: 2行空ける. -・中見出し(X-X)の上: 1行空ける. -・小見出し(■や数字)の上: 1行空ける. -・セクション内のリスト: 原則として行間を詰め、まとまりごとに適宜空行を入れる. -・ミニサンプル: - 1. 基本設計 (Basic Design) - ------------------------------------------------------------------------ - - - 1-1. 製品概要 - - ■ 主要要件 - ・要件A: 説明 - ・要件B: 説明 - - ■ 補足 - ・注意点: 説明 - -・NG例(空行不足): - 1. 基本設計 (Basic Design) - ------------------------------------------------------------------------ - 1-1. 製品概要 - ■ 主要要件 - ・要件A: 説明 - - -5. 技術記述・コード表記 (Technical & Code) ------------------------------------------------------------------------- -・コマンドライン: 先頭に `$ ` を付与して区別する. -・ディレクトリ構造: ツリー記号(`├──`, `│`, `└──`)を使用し,ルートディレクトリからの階層を示す. -・インデント: コードブロック内は,親の箇条書きレベルに合わせて開始位置を揃える. \ No newline at end of file diff --git "a/docs/02_Guide/GUIDE_02_\343\203\225\343\202\241\343\202\244\343\203\253\345\221\275\345\220\215\350\246\217\345\211\207.txt" "b/docs/02_Guide/GUIDE_02_\343\203\225\343\202\241\343\202\244\343\203\253\345\221\275\345\220\215\350\246\217\345\211\207.txt" deleted file mode 100644 index a8217e6..0000000 --- "a/docs/02_Guide/GUIDE_02_\343\203\225\343\202\241\343\202\244\343\203\253\345\221\275\345\220\215\350\246\217\345\211\207.txt" +++ /dev/null @@ -1,54 +0,0 @@ -======================================================================== -ドキュメント管理・ファイル命名規則 (File Naming Conventions) -======================================================================== - -1. 命名の基本方針 (Basic Policy) ------------------------------------------------------------------------- -プロジェクトの規模拡大に伴うファイルの散乱を防ぎ,開発メンバーおよびAI(Gemini/Copilot)がファイルの内容・文脈を即座に特定できるようにするため,以下の規則を適用する. -※ 書式・記述スタイルの基準は `GUIDE_01_ドキュメント作成ガイド.txt` を参照する. - -■ 基本フォーマット -`[カテゴリ]_[連番]_[ファイル名].txt` - -・区切り文字: アンダースコア `_` を使用する. -・連番: 01から始まる2桁の数字とする. -・拡張子: プレーンテキスト `.txt` とする. - - -2. カテゴリ定義 (Category Definitions) ------------------------------------------------------------------------- -ファイル名の先頭に付与するプレフィックス(接頭辞)定義. - -■ GUIDE_ (Guide) -・内容: チーム全体のルール,規約,運用フローなど,「メタ情報」に関する定義. -・対象例: スタイルガイド,命名規則,Git運用ルール. - -■ PLAN_ (Planning) -・内容: プロジェクトの進行計画,スケジュール,要件定義など,「管理・進行」に関する定義. -・対象例: WBS,ロードマップ,要件定義書,タスク一覧. - -■ ENV_ (Environment) -・内容: 開発環境,ディレクトリ構造,ライブラリ選定など,プロジェクトの「土台」に関する定義. -・対象例: 環境構築手順,技術スタック一覧,パッケージ構成図. - -■ SPEC_ (Specification) -・内容: 企画,ゲームルール,UI/UXなど,ユーザーから見える「仕様」に関する定義. -・対象例: ゲーム企画書,画面遷移図,パラメータ設定(マップサイズ・速度など). - -■ TECH_ (Technical) -・内容: 実装詳細,アルゴリズム,データ構造など,エンジニア向けの「技術設計」に関する定義. -・対象例: 通信プロトコル仕様,同期ロジック,データベース設計,クラス設計. - -■ TEST_ (Test) -・内容: テスト計画,テストケース,品質保証手順など,「検証・品質」に関する定義. -・対象例: 単体テスト仕様書,シナリオテスト計画,テストケース一覧,品質基準. - - -3. 運用ルール (Operational Rules) ------------------------------------------------------------------------- -・1ファイル1テーマ: - ファイルサイズが肥大化しすぎないよう,トピック(例: 通信仕様,判定ロジック)ごとにファイルを分割することを推奨する. - これにより,AIへのコンテキスト入力精度が向上する. - -・スタイルの継承: - 新規作成するファイルも,必ず `GUIDE_01_ドキュメント作成ガイド.txt` に記載された書式(見出し,句読点「,.」等)に従うこと. \ No newline at end of file diff --git "a/docs/02_Guide/GUIDE_03_Git\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.txt" "b/docs/02_Guide/GUIDE_03_Git\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.txt" deleted file mode 100644 index 2bff163..0000000 --- "a/docs/02_Guide/GUIDE_03_Git\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.txt" +++ /dev/null @@ -1,127 +0,0 @@ -======================================================================== -Git運用ルール (Git Operation Rules) -======================================================================== - -1. 基本方針 (Basic Policy) ------------------------------------------------------------------------- -チーム開発におけるコードの整合性を保ち,手戻りを防ぐために以下の運用フローを徹底する. - -・メインブランチ (main): - - 本番環境または常に動作可能な状態を維持するブランチ. - - 直接のコミット(直プッシュ)は禁止する.必ずプルリクエスト(PR)経由でマージする. -・作業ブランチ (Feature Branch): - - 機能追加やバグ修正ごとに `main` から派生させて作成する. - - 作業完了後,`main` へマージし,原則として削除する. - - -2. ブランチ命名規則 (Branch Naming) ------------------------------------------------------------------------- -2-1. プレフィックス (Prefix) -作業の種類を一目で判別するために,以下のプレフィックスを使用する. - -■ カテゴリ一覧 - ・feature/: 新機能の実装,仕様変更 - ・fix/: バグ修正 - ・refactor/: コードの整理(挙動は変えない) - ・docs/: ドキュメントの追記・修正 - ・chore/: ビルド設定やツール導入など,雑多な作業 - -2-2. 書式 (Format) - ・書式: `[プレフィックス][日付(YYMMDD)]_[名前]_[概要]` - ・区切り: スラッシュ `/` および アンダースコア `_` を使用する. - ・例: - - feature/260207_yamada_player_jump - - fix/260208_tanaka_collision_bug - - docs/260210_suzuki_guide_update - - -3. 開発フロー (Development Workflow) ------------------------------------------------------------------------- -作業を開始してからマージされるまでの手順. - -1. ローカルの最新化 - ・作業開始前は必ず `main` ブランチに切り替え,リモートの最新状態を取り込む. - ・コマンド: - $ git checkout main - $ git pull origin main - -2. 作業ブランチの作成 - ・最新の `main` から新しいブランチを作成して移動する. - ・コマンド: - $ git checkout -b feature/260214_yamada_new_function - -3. 実装とコミット - ・作業単位(意味のあるまとまり)ごとにコミットする. - ・巨大なコミットは避け,レビューしやすい粒度を心がける. - ・VS CodeでCopilotを使用している場合,AIによるコミットメッセージの生成機能(キラキラアイコン等)を利用してもよい. - ただし,生成されたメッセージは必ず「4. コミットメッセージ」の書式ルール(タグや日本語化)に合わせて修正すること. - ・コマンド: - $ git add . - $ git commit -m "[add] 新機能を実装" - -4. リモートへのプッシュ - ・作業ブランチをリモートリポジトリへ送信する. - ・コマンド: - $ git push origin feature/260214_yamada_new_function - -5. プルリクエスト (PR) の作成 - ・GitHubのリポジトリ画面上部に表示される「Compare & pull request」ボタンをクリックする. - ・Baseを `main`、Compareを自分の「作業ブランチ」に設定する. - ・「Reviewers」メニューからチームメンバーを選択し、レビューを依頼する. - ・「Create pull request」ボタンを押してPRをオープンする. - -6. レビューと修正の対応 - ・レビュワーのコメントを確認し、修正が必要な場合はローカルで修正・コミット・プッシュを繰り返す. - ・GitHub上で全ての指摘に対し「Resolve conversation」を行い、やり取りを完了させる. - ・レビュワーから「Approve(承認)」のスタンプまたはメッセージをもらう. - -7. マージの実行(マージボタンの操作) - ・PR画面下部の「Merge pull request」ボタンをクリックする. - ・確認用の「Confirm merge」ボタンを押し、`main` への統合を完了させる. - ・マージ直後に表示される「Delete branch」ボタンを押し、リモート上の作業ブランチを削除する. - -8. ローカル環境のクリーンアップ - ・マージ完了後はローカル環境も最新状態に戻し、古いブランチを削除する. - $ git checkout main - $ git pull origin main - $ git branch -d [作業ブランチ名] - - -4. コミットメッセージ (Commit Messages) ------------------------------------------------------------------------- -4-1. 書式 - ・書式: `[タグ] 内容` - ・言語: 日本語 (Japanese) - ・句読点: 末尾に句点は不要. - -4-2. タグ一覧 - ・[add]: ファイルや機能の追加 - ・[update]: 機能やデータの更新・修正 - ・[fix]: バグ修正 - ・[remove]: 削除 - ・[clean]: 整理,リファクタリング - - -5. トラブルシューティング (Troubleshooting) ------------------------------------------------------------------------- -■ コンフリクト (Conflict) が発生した場合 -他メンバーの変更と競合した場合の対処手順. - -1. main の取り込み - ・作業ブランチに `main` の最新内容をマージして競合箇所を洗い出す. - ・コマンド: - $ git checkout main - $ git pull origin main - $ git checkout feature/260214_yamada_new_function - $ git merge main - -2. 競合の解消 - ・エディタ上で `<<<<<<<`, `=======`, `>>>>>>>` で囲まれた箇所を手動で修正する. - ・修正後,再度コミットしてプッシュする. - -■ 間違えて main にコミットしてしまった場合 - ・まだプッシュしていない場合,コミットを取り消して新しいブランチへ移動させる. - ・コマンド: - $ git reset --soft HEAD^ - $ git checkout -b feature/260214_yamada_new_function - $ git commit -m "..." \ No newline at end of file diff --git "a/docs/02_Guide/GUIDE_04_\343\202\263\343\203\274\343\203\211\343\202\263\343\203\241\343\203\263\343\203\210\350\246\217\345\211\207.txt" "b/docs/02_Guide/GUIDE_04_\343\202\263\343\203\274\343\203\211\343\202\263\343\203\241\343\203\263\343\203\210\350\246\217\345\211\207.txt" deleted file mode 100644 index 2faa119..0000000 --- "a/docs/02_Guide/GUIDE_04_\343\202\263\343\203\274\343\203\211\343\202\263\343\203\241\343\203\263\343\203\210\350\246\217\345\211\207.txt" +++ /dev/null @@ -1,124 +0,0 @@ -======================================================================== -コードコメント・ドキュメント規則 (Code Comment & Documentation Guide) -======================================================================== - - -1. 基本方針 (Basic Policy) ------------------------------------------------------------------------- -コードの可読性と保守性を高めるため,ファイル・型・関数・定数それぞれに対して -適切な粒度でコメントを記述する. - -・言語: 日本語で記述する. -・句読点: 「,」(全角カンマ)を使用し,文末の句点(「.」「。」)は付けない - - 列挙が続く場合は「,」で区切る -・文体: 体言止め,または「〜する」形で統一する - - -2. コメントの種類と用途 (Comment Types) ------------------------------------------------------------------------- - -2-1. ファイルドキュメント (File Header Doc Comment) - ・ファイルの先頭に必ず記述する. - ・JSDoc形式(`/** */`)を使用する. - ・書式: - - /** - * [ファイル名(拡張子なし)] - * [ファイルの主な責務を1行で説明] - * [補足情報があれば続けて記述] - */ - - ・例: - - /** - * useJoystick - * ジョイスティック入力を受け取り,座標計算と正規化ベクトルの出力を行うフック - * UI描画に必要な中心点・ノブ位置・半径も合わせて提供する - */ - -2-2. 型・定数ドキュメント (Type & Constant Doc Comment) - ・`export` される型(`type`,`interface`)および定数(`const`)には必ず記述する. - ・JSDoc形式の1行コメント(`/** */`)を直前行に記述する. - ・書式: - - /** [その型・定数が何を表すかを端的に説明] */ - export type / const ... - - ・例: - - /** UI側と共有する最大半径の既定値 */ - export const MAX_DIST = 60; - - /** 2D座標の簡易型 */ - type Point = { x: number; y: number }; - - /** フックが返すUI向けの状態とハンドラ */ - type UseJoystickReturn = { ... }; - -2-3. 関数・コンポーネント・フックドキュメント (Function Doc Comment) - ・`export` される関数,Reactコンポーネント,フックには必ず記述する. - ・JSDoc形式の1行コメント(`/** */`)を直前行に記述する. - ・書式: - - /** [その関数・コンポーネントが何をするかを端的に説明] */ - export const / function ... - - ・例: - - /** 正規化ベクトルの出力とUI用の座標を提供するフック */ - export const useJoystick = ... - - /** ポインター入力と描画を結びつけるジョイスティックUI */ - export const Joystick = ... - -2-4. ブロックコメント (Block Comment) - ・関数・コンポーネント内で,処理のまとまりが変わる箇所に記述する. - ・通常の行コメント(`//`)を使用する. - ・書式: - - // [このブロックの処理を端的に説明] - ...処理... - - ・例: - - // 入力開始時の基準座標をセットする - const handleStart = ... - - // 入力座標からベクトルを計算し,半径でクランプして正規化出力する - const handleMove = ... - -2-5. JSXコメント (JSX Comment) - ・JSX内のブロック区切りには `{/* */}` 形式を使用する. - ・例: - - {/* 見た目のみの描画(入力は扱わない) */} - - -2-6. 再エクスポートコメント (Re-export Comment) - ・外部へ再公開する `export { ... }` には1行ドキュメントを付ける. - ・例: - - /** 入力半径の既定値を外部から参照できるように再公開 */ - export { MAX_DIST } from "./useJoystick"; - - -3. 記述しない場合の判断基準 (When to Omit) ------------------------------------------------------------------------- -・ファイル内部でのみ使用し,外部に公開されない型・関数・定数は省略してもよい -・コード自体が自明な場合(変数名で意図が十分伝わる場合)は省略してもよい -・ユニットテストファイルは,テストケース名で意図が伝わる場合は省略してもよい - - -4. NG例 (Anti-patterns) ------------------------------------------------------------------------- -・句点を付ける - - NG: /** ジョイスティックの入力を受け取る. */ - - OK: /** ジョイスティックの入力を受け取る */ - -・「、」「。」を使う - - NG: // 入力開始時の基準座標をセットする。 - - OK: // 入力開始時の基準座標をセットする - -・ファイルヘッダーを通常の行コメントで書く - - NG: // useJoystick: ジョイスティック入力を受け取るフック - - OK: /** \n * useJoystick\n * ジョイスティック入力を受け取るフック\n */ diff --git "a/docs/02_Guide/GUIDE_05_\343\203\227\343\203\255\343\203\210\343\202\263\343\203\253\350\277\275\345\212\240\346\211\213\351\240\206.txt" "b/docs/02_Guide/GUIDE_05_\343\203\227\343\203\255\343\203\210\343\202\263\343\203\253\350\277\275\345\212\240\346\211\213\351\240\206.txt" deleted file mode 100644 index 3104ac6..0000000 --- "a/docs/02_Guide/GUIDE_05_\343\203\227\343\203\255\343\203\210\343\202\263\343\203\253\350\277\275\345\212\240\346\211\213\351\240\206.txt" +++ /dev/null @@ -1,111 +0,0 @@ -======================================================================== -プロトコル追加手順 (Protocol Extension Guide) -======================================================================== - - -1. 目的 (Purpose) ------------------------------------------------------------------------- -本ドキュメントは,ソケットイベントの追加・変更時に,修正箇所の漏れを防ぐための標準手順を定義する. -`packages/shared/src/protocol` の責務分割方針に従い,イベント名,ペイロード型,方向別マップ,公開エントリを順に更新する. - - -2. 適用対象 (Scope) ------------------------------------------------------------------------- -・対象レイヤ: shared プロトコル定義(client/server 共通契約) -・対象ディレクトリ: `packages/shared/src/protocol` -・対象ユースケース: 新規イベント追加,既存イベントのペイロード変更,イベント廃止 - - -3. ディレクトリ構成 (Directory Layout) ------------------------------------------------------------------------- -・基準構成は以下とする. - - packages/shared/src/protocol/ - ├── socketEvents.ts - ├── eventPayloads.ts - ├── eventPayloadMaps.ts - ├── events.ts - ├── socketEventBridge.ts - ├── payloads/ - │ ├── commonPayloads.ts - │ ├── lobbyPayloads.ts - │ └── gamePayloads.ts - └── maps/ - ├── commonEventPayloadMap.ts - ├── lobbyEventPayloadMap.ts - └── gameEventPayloadMap.ts - - -4. 標準追加フロー (Standard Flow) ------------------------------------------------------------------------- -新規イベントを追加する場合は,必ず次の順で更新する. - -4-1. イベント名を追加する - ・ファイル: socketEvents.ts - ・作業: `SocketEvents` にイベント名を追加する - ・確認: 命名規則(kebab-case / snake_case)を既存方針に合わせる - -4-2. ペイロード型を追加する - ・ファイル: payloads/commonPayloads.ts または payloads/lobbyPayloads.ts または payloads/gamePayloads.ts - ・作業: イベントに対応する payload 型を追加する - ・確認: 既存型の再利用可否を確認し,重複定義を避ける - -4-3. 方向別マップへ対応を追加する - ・ファイル: maps/commonEventPayloadMap.ts / maps/lobbyEventPayloadMap.ts / maps/gameEventPayloadMap.ts - ・作業: 追加イベントを C→S または S→C の適切な map に追記する - ・確認: 方向が誤っていないかを必ず確認する - -4-4. 集約エントリの再公開を調整する - ・ファイル: eventPayloads.ts / eventPayloadMaps.ts / events.ts - ・作業: 外部利用が必要な型のみ再公開する - ・確認: 既存 import パス互換(`@repo/shared` 経由)を維持する - -4-5. 利用側を接続する - ・対象: client/server の handler / bridge / useCase - ・作業: on/off/emit と payload 型参照を更新する - - -5. 変更時のチェックポイント (Checklist) ------------------------------------------------------------------------- -・イベント名追加済みか -・payload 型追加済みか -・map への方向別登録済みか -・events.ts 再公開が過不足ないか -・client/server で型エラーがないか -・既存イベントの型互換を壊していないか -・player 座標差分イベント(SocketEvents.UPDATE_PLAYERS / update-players)に teamId を含めていないか -・初期同期イベント(SocketEvents.CURRENT_PLAYERS / current-players,SocketEvents.NEW_PLAYER / new-player)に teamId を含めているか - - -6. 典型ミスと対策 (Common Pitfalls) ------------------------------------------------------------------------- -■ イベント名だけ追加して map を更新しない -・症状: emit/on の型推論が崩れる,もしくは any 化する -・対策: 4-3 を必須工程として実施する - -■ payload 定義場所が不適切 -・症状: common/lobby/game の境界が曖昧になる -・対策: イベント責務に従って payloads 配下へ配置する - -■ 循環参照を作る -・症状: 型解決エラー,TS2307/TS2456 系が発生しやすくなる -・対策: `events.ts` は再公開専用とし,型本体は payload 側へ置く - - -7. 検証コマンド (Validation Commands) ------------------------------------------------------------------------- -・shared 型定義のビルド確認 - $ pnpm --filter @repo/shared build - -・サーバー互換確認 - $ pnpm --filter server build - -・クライアント互換確認 - $ pnpm --filter client build - - -8. 運用ルール (Operation Rules) ------------------------------------------------------------------------- -・プロトコル追加時は,本ガイドの 4-1 から 4-5 までを PR テンプレート上でチェックする -・events.ts に型本体を戻さない(再公開専用を維持する) -・新規型のコメントは `GUIDE_04_コードコメント規則` に従う diff --git "a/docs/03_PLAN/PLAN_01_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210\345\256\237\350\243\205\350\250\210\347\224\273.txt" "b/docs/03_PLAN/PLAN_01_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210\345\256\237\350\243\205\350\250\210\347\224\273.txt" new file mode 100644 index 0000000..262bd72 --- /dev/null +++ "b/docs/03_PLAN/PLAN_01_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210\345\256\237\350\243\205\350\250\210\347\224\273.txt" @@ -0,0 +1,79 @@ +======================================================================== +Pixel Paint War - プロトタイプ実装計画 (Prototype Implementation Plan) +======================================================================== + +1. 概要 (Overview) +------------------------------------------------------------------------ +本ドキュメントは,「SPEC_03_プロトタイプ_移動テスト.txt」で定義された50人同時接続テストを達成するための段階的な実装ロードマップである. +複雑性を排除するため,最小構成から機能を積み上げる(Step-by-Step)方式を採用する. + + +2. 実装フェーズ定義 (Implementation Phases) +------------------------------------------------------------------------ + +2-1. Step 1: クライアント単体移動 (Local Movement) + ■ 目標 + サーバーを介さず,ブラウザ上でジョイスティック操作によりキャラクターが移動・描画されること. + + ■ 実装対象 + ・packages/shared/ + - src/config/gameConfig.ts: マップサイズ,移動速度等の定数定義. + - src/utils/math.ts: ベクトル計算,移動ロジック (Pos += Vel * Speed * DT). + ・apps/client/ + - src/input/Joystick.ts: タッチ入力の正規化,デッドゾーン処理. + - src/entities/PlayerSprite.ts: 描画更新処理. + - src/core/GameLoop.ts: Pixi.js Tickerを用いたメインループ. + +2-2. Step 2: サーバー開通・単体通信 (Single Player Network) + ■ 目標 + WebSocketサーバーと接続し,バイナリパケットの送受信(エコーテスト)に成功すること. + + ■ 実装対象 + ・packages/shared/ + - src/protocol/schema.ts: DataViewを用いたバイナリエンコード/デコード処理. + ・apps/server/ + - src/index.ts: WebSocketサーバー起動 (wsライブラリ). + - src/network/Connection.ts: 接続管理. + ・apps/client/ + - src/network/SocketClient.ts: バイナリ送受信の実装. + +2-3. Step 3: 複数人同期・補間 (Multiplayer Sync) + ■ 目標 + 2つのクライアント間で位置同期が行われ,他プレイヤーの動きが補間により滑らかに表示されること. + + ■ 実装対象 + ・apps/server/ + - src/managers/RoomManager.ts: 接続IDと座標の管理. + - src/network/PacketHandler.ts: 全員分の座標スナップショット作成とブロードキャスト. + ・apps/client/ + - src/entities/RemotePlayer.ts: 他プレイヤー描画クラス. + - src/network/Reconciler.ts: 線形補間 (Lerp) ロジックの実装. + +2-4. Step 4: 50人規模最適化 (Optimization & Scaling) + ■ 目標 + パケットサイズを削減し,50人同時動作時の帯域負荷を仕様内(30KB/s以下)に抑えること. + + ■ 実装対象 + ・packages/shared/ + - src/utils/quantization.ts: 座標の圧縮 (Float -> Uint16). + ・apps/server/ + - src/core/ServerEngine.ts: ループ処理の最適化,必要に応じたAoI(関心領域)判定. + +2-5. Step 5: メタデータ・UI実装 (Meta Data & UI) + ■ 目標 + ゲーム開始前のロビー画面およびUIを実装し,ゲームサイクルを完成させること. + + ■ 実装対象 + ・apps/client/ + - src/scenes/TitleScene.ts: 名前入力とスタート処理. + - src/ui/UIManager.ts: DOMベースのUIオーバーレイ. + ・packages/shared/ + - src/types/index.ts: ロビー用JSONメッセージの型定義. + + +3. 開発ルール (Development Rules) +------------------------------------------------------------------------ +・ロジックの共通化: + 移動計算式や衝突判定は必ず `packages/shared` に実装し,Client/Server間でコードを共有する. +・検証優先: + 各Step完了ごとに動作確認を行い,バグを次工程に持ち越さない. \ No newline at end of file diff --git "a/docs/03_Plan/PLAN_01_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210\345\256\237\350\243\205\350\250\210\347\224\273.txt" "b/docs/03_Plan/PLAN_01_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210\345\256\237\350\243\205\350\250\210\347\224\273.txt" deleted file mode 100644 index 262bd72..0000000 --- "a/docs/03_Plan/PLAN_01_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210\345\256\237\350\243\205\350\250\210\347\224\273.txt" +++ /dev/null @@ -1,79 +0,0 @@ -======================================================================== -Pixel Paint War - プロトタイプ実装計画 (Prototype Implementation Plan) -======================================================================== - -1. 概要 (Overview) ------------------------------------------------------------------------- -本ドキュメントは,「SPEC_03_プロトタイプ_移動テスト.txt」で定義された50人同時接続テストを達成するための段階的な実装ロードマップである. -複雑性を排除するため,最小構成から機能を積み上げる(Step-by-Step)方式を採用する. - - -2. 実装フェーズ定義 (Implementation Phases) ------------------------------------------------------------------------- - -2-1. Step 1: クライアント単体移動 (Local Movement) - ■ 目標 - サーバーを介さず,ブラウザ上でジョイスティック操作によりキャラクターが移動・描画されること. - - ■ 実装対象 - ・packages/shared/ - - src/config/gameConfig.ts: マップサイズ,移動速度等の定数定義. - - src/utils/math.ts: ベクトル計算,移動ロジック (Pos += Vel * Speed * DT). - ・apps/client/ - - src/input/Joystick.ts: タッチ入力の正規化,デッドゾーン処理. - - src/entities/PlayerSprite.ts: 描画更新処理. - - src/core/GameLoop.ts: Pixi.js Tickerを用いたメインループ. - -2-2. Step 2: サーバー開通・単体通信 (Single Player Network) - ■ 目標 - WebSocketサーバーと接続し,バイナリパケットの送受信(エコーテスト)に成功すること. - - ■ 実装対象 - ・packages/shared/ - - src/protocol/schema.ts: DataViewを用いたバイナリエンコード/デコード処理. - ・apps/server/ - - src/index.ts: WebSocketサーバー起動 (wsライブラリ). - - src/network/Connection.ts: 接続管理. - ・apps/client/ - - src/network/SocketClient.ts: バイナリ送受信の実装. - -2-3. Step 3: 複数人同期・補間 (Multiplayer Sync) - ■ 目標 - 2つのクライアント間で位置同期が行われ,他プレイヤーの動きが補間により滑らかに表示されること. - - ■ 実装対象 - ・apps/server/ - - src/managers/RoomManager.ts: 接続IDと座標の管理. - - src/network/PacketHandler.ts: 全員分の座標スナップショット作成とブロードキャスト. - ・apps/client/ - - src/entities/RemotePlayer.ts: 他プレイヤー描画クラス. - - src/network/Reconciler.ts: 線形補間 (Lerp) ロジックの実装. - -2-4. Step 4: 50人規模最適化 (Optimization & Scaling) - ■ 目標 - パケットサイズを削減し,50人同時動作時の帯域負荷を仕様内(30KB/s以下)に抑えること. - - ■ 実装対象 - ・packages/shared/ - - src/utils/quantization.ts: 座標の圧縮 (Float -> Uint16). - ・apps/server/ - - src/core/ServerEngine.ts: ループ処理の最適化,必要に応じたAoI(関心領域)判定. - -2-5. Step 5: メタデータ・UI実装 (Meta Data & UI) - ■ 目標 - ゲーム開始前のロビー画面およびUIを実装し,ゲームサイクルを完成させること. - - ■ 実装対象 - ・apps/client/ - - src/scenes/TitleScene.ts: 名前入力とスタート処理. - - src/ui/UIManager.ts: DOMベースのUIオーバーレイ. - ・packages/shared/ - - src/types/index.ts: ロビー用JSONメッセージの型定義. - - -3. 開発ルール (Development Rules) ------------------------------------------------------------------------- -・ロジックの共通化: - 移動計算式や衝突判定は必ず `packages/shared` に実装し,Client/Server間でコードを共有する. -・検証優先: - 各Step完了ごとに動作確認を行い,バグを次工程に持ち越さない. \ No newline at end of file diff --git "a/docs/04_SPEC/SPEC_01_\343\202\262\343\203\274\343\203\240\346\246\202\350\246\201_\347\224\273\351\235\242\351\201\267\347\247\273.txt" "b/docs/04_SPEC/SPEC_01_\343\202\262\343\203\274\343\203\240\346\246\202\350\246\201_\347\224\273\351\235\242\351\201\267\347\247\273.txt" new file mode 100644 index 0000000..1886005 --- /dev/null +++ "b/docs/04_SPEC/SPEC_01_\343\202\262\343\203\274\343\203\240\346\246\202\350\246\201_\347\224\273\351\235\242\351\201\267\347\247\273.txt" @@ -0,0 +1,77 @@ +======================================================================== +ゲーム概要・画面遷移仕様 (Game Overview & Screen Flow) +======================================================================== + + +1. ゲーム概要 (Game Overview) +------------------------------------------------------------------------ + +1-1. コンセプト + チーム対抗の陣取りペイントバトルゲーム. + 複数のプレイヤーがリアルタイムで同じフィールドに参加し,自チームの色でマスを塗りつぶして陣地を広げる. + 制限時間内に最も多くの面積を塗ったチームが勝利する. + +1-2. 基本仕様 + ・ジャンル: チーム対抗リアルタイム陣取りゲーム + ・チーム数: 4チーム(赤・青・緑・黄) + ・制限時間: 180秒(3分) + ・勝利条件: 終了時に最も多くのセルを塗ったチームが1位 + ・対応プラットフォーム: ブラウザ(モバイル・PC) + ・画面方向: 横画面固定(ランドスケープ) + +1-3. ゲームの流れ + 1. プレイヤーがルームに参加する + 2. ホストがゲーム設定を行い,ゲームを開始する + 3. 制限時間内にフィールドを移動し,ボムを設置して自チームの色でマスを塗る + 4. 制限時間終了後,チーム別の塗り面積で順位が決定する + + +2. 画面遷移 (Screen Flow) +------------------------------------------------------------------------ + +2-1. 画面一覧 + ・タイトル画面: ゲームへの入口,プレイヤー名とルームIDを入力して入室する + ・ロビー画面: ゲーム開始前の待機画面,参加者一覧とゲーム設定を表示する + ・ゲーム画面: メインのゲームプレイ画面,移動とボム設置を行う + ・リザルト画面: ゲーム終了後の結果表示画面 + +2-2. 遷移フロー + タイトル → ロビー → ゲーム → リザルト → タイトル + + ■ タイトル → ロビー + ・トリガー: プレイヤー名とルームIDを入力し「GAME START」ボタンを押す + ・条件: サーバーから入室許可を受け取った場合に遷移する + ・失敗時: エラーメッセージを表示し,タイトル画面に留まる + + ■ ロビー → ゲーム + ・トリガー: ホストが「ゲームスタート」ボタンを押す + ・条件: サーバーからゲーム開始通知を受信した全員が遷移する + + ■ ゲーム → リザルト + ・トリガー: 制限時間終了(サーバーからゲーム終了+結果通知を受信) + ・自動遷移: プレイヤー操作不要で遷移する + + ■ リザルト → タイトル + ・トリガー: 「タイトルへ戻る」ボタンを押す + + +3. チーム仕様 (Team Specification) +------------------------------------------------------------------------ + +3-1. チーム構成 + ・チーム数: 4 + ・チーム名とID: + - ID 0: 赤チーム + - ID 1: 青チーム + - ID 2: 緑チーム + - ID 3: 黄チーム + +3-2. チーム割り当て方式 + ・ランダム(random): サーバーが人数バランスを考慮して自動割り当てする + ・プレイヤー選択(player_select): プレイヤーが希望チームを選択する + - 満員のチームは選択できない + - 未選択の場合はランダムに割り当てられる + +3-3. Bot(AI プレイヤー) + ・目標人数に対して人数が不足する場合,Botが自動的に補充される + ・接続切断したプレイヤーはBotに置き換えられる diff --git "a/docs/04_SPEC/SPEC_02_\343\203\255\343\203\223\343\203\274\344\273\225\346\247\230.txt" "b/docs/04_SPEC/SPEC_02_\343\203\255\343\203\223\343\203\274\344\273\225\346\247\230.txt" new file mode 100644 index 0000000..3808159 --- /dev/null +++ "b/docs/04_SPEC/SPEC_02_\343\203\255\343\203\223\343\203\274\344\273\225\346\247\230.txt" @@ -0,0 +1,80 @@ +======================================================================== +ロビー仕様 (Lobby Specification) +======================================================================== + + +1. タイトル画面 (Title Screen) +------------------------------------------------------------------------ + +1-1. 画面構成 + ・背景: タイトル画像(title.png)を全画面表示する + ・初期状態: 「- TAP TO START -」が点滅表示される + ・タップ後: 入力フォームがフェードインで表示される + +1-2. 入力項目 + ・プレイヤー名: テキスト入力(必須) + ・ルームID: テキスト入力(必須) + +1-3. 入室操作 + ・「GAME START」ボタンを押すとサーバーへ入室リクエストを送信する + ・送信中はボタンが「接続中...」表示になり,非活性化される + ・両方の入力が空でない場合のみボタンが活性化される + +1-4. 入室拒否 + サーバーから拒否された場合,エラーメッセージを表示する. + ・満員(full): ルームの最大人数に達している + ・重複(duplicate): 同じ接続IDで既に入室済み + ・ゲーム中(playing): ルームが既にゲーム中である + + +2. ロビー画面 (Lobby Screen) +------------------------------------------------------------------------ + +2-1. 画面レイアウト + ・左上: 「タイトルへ戻る」ボタン + ・上部中央: ルームIDと「(待機中)」ステータス表示 + ・左半分: ゲーム操作パネル(スタートボタン or 待機メッセージ) + ・右半分: 参加プレイヤーリスト + +2-2. ホスト(オーナー)向け表示 + + ■ ゲーム設定(歯車ボタンからモーダルで開く) + ・目標人数: 4人刻みで選択(最小: 現在の参加人数を4の倍数に切り上げ,最大: 100) + - 不足分はBotが補充される + ・フィールドサイズ: プリセットから選択 + - SMALL: 推奨 4〜20人 + - MEDIUM: 推奨 20〜40人(既定値) + - LARGE: 推奨 40〜70人 + - XLARGE: 推奨 70〜100人 + ・チーム割り当て方式: ランダム / プレイヤーが選択 + + ■ 操作ボタン + ・「ゲームスタート」ボタン: 押すと確認モーダルが表示される + ・「ルールを見る」ボタン: ゲームルール説明モーダルが開く + +2-3. メンバー(非オーナー)向け表示 + ・「ホストの開始を待っています...」メッセージ + ・ホストが設定したゲーム人数・フィールドサイズ・チーム割り当て方式の表示 + ・「ルールを見る」ボタン + +2-4. チーム選択 + ・チーム割り当て方式が「プレイヤーが選択」の場合に有効になる + ・選択肢: ランダム / 赤チーム / 青チーム / 緑チーム / 黄チーム + ・満員のチームを選択した場合,「このチームは満員です」メッセージが3秒間表示される + ・「ランダム」の場合は自動モードと同様にサーバーが割り当てる + +2-5. プレイヤーリスト + ・表示内容: プレイヤー名,オーナーマーク(王冠),自分マーク(緑丸) + ・チーム選択モード時: 選択チーム名をチームカラーで表示する + ・ソート順: 入った順(既定) / チーム順 / 名前順 + - チーム順はチーム選択モード時のみ選択可能 + ・ヘッダー: 「参加プレイヤー (現在人数/最大人数)」 + +2-6. ゲーム開始確認モーダル + ・ホストが「ゲームスタート」を押すと表示される + ・確認ボタンとキャンセルボタンがある + ・確認を押すとサーバーにゲーム開始リクエストを送信する + +2-7. 設定のリアルタイム同期 + ・ホストが設定を変更すると,サーバー経由で全メンバーに即時反映される + ・メンバー側では設定項目は閲覧のみ(変更不可) diff --git "a/docs/04_SPEC/SPEC_03_\343\202\262\343\203\274\343\203\240\343\203\227\343\203\254\343\202\244\344\273\225\346\247\230.txt" "b/docs/04_SPEC/SPEC_03_\343\202\262\343\203\274\343\203\240\343\203\227\343\203\254\343\202\244\344\273\225\346\247\230.txt" new file mode 100644 index 0000000..c3d0aba --- /dev/null +++ "b/docs/04_SPEC/SPEC_03_\343\202\262\343\203\274\343\203\240\343\203\227\343\203\254\343\202\244\344\273\225\346\247\230.txt" @@ -0,0 +1,144 @@ +======================================================================== +ゲームプレイ仕様 (Gameplay Specification) +======================================================================== + + +1. ゲーム進行 (Game Progression) +------------------------------------------------------------------------ + +1-1. タイムライン + ・開始カウントダウン: ゲーム開始通知から5秒間のカウントダウン後にプレイ開始 + ・通常フェーズ: 0〜120秒(残り180〜60秒) + ・フィーバータイム: 残り60秒から発動,ボムクールダウンが短縮される + ・ハリケーン出現: 残り120秒から出現する(ゲーム開始60秒経過後) + ・塗り率非表示: 残り30秒からチーム塗り率が隠される + ・ゲーム終了: 残り0秒でサーバーがゲーム終了を通知する + +1-2. 勝敗判定 + ・制限時間終了時のチーム別塗りセル数で順位を決定する + ・塗りセル数が最も多いチームが1位となる + + +2. フィールド仕様 (Field Specification) +------------------------------------------------------------------------ + +2-1. マップ構造 + ・グリッドベースのセル構造 + ・各セルはチームIDを保持する + - 未塗装: -1 + - チーム塗装: 0〜3(チームIDに対応) + ・座標系: 浮動小数点のグリッド座標(左上が原点) + +2-2. フィールドサイズプリセット + フィールドの実グリッドサイズは AOIセル数 × AOIセルサイズ(3)で算出される. + + | プリセット | AOIセル数 | 実グリッドサイズ | 推奨人数 | + | :--------- | :-------- | :--------------- | :----------- | + | SMALL | 8×8 | 24×24 | 4〜20人 | + | MEDIUM | 12×12 | 36×36 | 20〜40人 | + | LARGE | 15×15 | 45×45 | 40〜70人 | + | XLARGE | 18×18 | 54×54 | 70〜100人 | + +2-3. セル塗り処理 + ・プレイヤーが移動するとそのセルが自チームの色で塗られる + ・競合処理: 同一セルに複数チームのプレイヤーが同時に存在する場合,そのセルは塗られない + ・既に他チームが塗ったセルは上書きできる + + +3. プレイヤー操作 (Player Controls) +------------------------------------------------------------------------ + +3-1. 移動 + ・入力方式: 画面左側のバーチャルジョイスティック(タッチ操作) + ・方向: 360度全方位入力 + ・移動速度: 3グリッド/秒 + ・プレイヤー半径: 0.5グリッド + ・座標管理: 浮動小数点で管理し,滑らかな移動を実現する + ・カメラ: 自プレイヤーを常に画面中央に追従する + +3-2. ボム設置 + ・入力方式: 画面右側のボムボタンをタップ + ・設置位置: プレイヤーの現在座標 + ・爆発までの時間(信管): 1000ms + ・爆発半径: 1.5グリッド(円形判定) + ・クールダウン: + - 通常時: 4000ms + - フィーバータイム時: 2000ms + +3-3. フィーバータイム + ・発動条件: ゲーム残り時間が60秒以下になった時点 + ・効果: ボムのクールダウンが4000msから2000msに短縮される + ・画面表示: 「!Fever Time!」通知が表示される + + +4. 被弾・リスポーン (Hit & Respawn) +------------------------------------------------------------------------ + +4-1. 被弾判定 + ・ボム爆発時,爆発半径内にいるプレイヤーに被弾判定が発生する + ・自チームのボムでは被弾しない + ・被弾したプレイヤーの被弾カウントが1増加する + +4-2. 被弾スタン + ・被弾時に1000msの間,入力が無効化される(スタン状態) + ・スタン中はプレイヤーが点滅する視覚エフェクトが表示される + +4-3. リスポーン + ・条件: 被弾カウントが5に達した場合にリスポーンが発生する + ・リスポーンスタン: 2000msの間,入力が無効化される + ・リスポーン位置: ゲーム開始時の初期スポーン地点 + ・被弾カウントはリスポーン後にリセットされる + + +5. ハリケーン (Hurricane Hazard) +------------------------------------------------------------------------ + +5-1. 出現条件 + ・ゲーム残り時間が120秒以下になった時点で出現する + ・同時出現数: 最大5個 + +5-2. ハリケーンの挙動 + ・直径: 2.2グリッド + ・移動速度: 1.5グリッド/秒 + ・移動方式: 直線移動し,フィールドの壁に当たると反射する + ・回転: 2.6 rad/秒で視覚的に回転する + +5-3. プレイヤーへの影響 + ・ハリケーンの範囲内に入ったプレイヤーはリスポーンが発生する + ・同一プレイヤーへの連続被弾クールダウン: 3000ms + ・画面表示: 出現時に「WARNING: ハリケーン出現」警告が表示される + + +6. Bot(AI プレイヤー) (Bot AI) +------------------------------------------------------------------------ + +6-1. 行動パターン + ・移動: 未塗装のセルを優先的に目標として移動する + ・ボム設置: 1ティック(50ms)あたり約6%の確率でボムを設置する + ・被弾時: 人間プレイヤーと同じスタン・リスポーン処理が適用される + +6-2. 補充ルール + ・目標人数に対して人間プレイヤーが不足する場合,Botが自動補充される + ・チームバランスを考慮して各チームに均等に配置される + + +7. サーバー同期 (Server Synchronization) +------------------------------------------------------------------------ + +7-1. ゲームループ + ・サーバーのティックレート: 20Hz(50ms間隔) + ・各ティックで実行される処理: + 1. ハリケーンの位置更新と衝突判定 + 2. Bot AIの行動決定 + 3. マップの塗り処理と競合判定 + 4. ボムの爆発判定(Bot向け) + 5. 差分データの組み立てとブロードキャスト + +7-2. 位置同期 + ・クライアントからサーバーへ: 50ms間隔でプレイヤー座標を送信する + ・サーバーからクライアントへ: 変化があったプレイヤーの座標のみを差分送信する + ・座標の量子化: Float座標をスケール100で整数化し,帯域を削減する + +7-3. 時刻同期 + ・Ping/Pongベースのクロック同期でクライアント・サーバー間の時刻差を推定する + ・推定オフセットはスムージングされ,急激な変動を抑制する diff --git "a/docs/04_SPEC/SPEC_04_HUD_UI\344\273\225\346\247\230.txt" "b/docs/04_SPEC/SPEC_04_HUD_UI\344\273\225\346\247\230.txt" new file mode 100644 index 0000000..d29ccc6 --- /dev/null +++ "b/docs/04_SPEC/SPEC_04_HUD_UI\344\273\225\346\247\230.txt" @@ -0,0 +1,153 @@ +======================================================================== +HUD・UI仕様 (HUD & UI Specification) +======================================================================== + + +1. ゲーム画面レイアウト (Game Screen Layout) +------------------------------------------------------------------------ + +1-1. レイヤー構成 + ゲーム画面は以下の3レイヤーで構成される(下から順). + + 1. PixiJS描画レイヤー: マップ・プレイヤー・ボム・ハリケーンの描画 + 2. HUDレイヤー: タイマー・HP・塗り率・ミニマップの表示 + 3. 入力レイヤー: ジョイスティック・ボムボタンのタッチ入力 + +1-2. 配置 + ・左上: タイマー + ・左側: HPゲージ + ・右上: ミニマップ + チーム塗り率パネル + ・左側(入力): ジョイスティック + ・右側(入力): ボムボタン + ・中央: カウントダウン・通知テキスト + + +2. タイマー (Timer) +------------------------------------------------------------------------ + +2-1. 表示仕様 + ・位置: 画面左上 + ・形式: MM:SS(分:秒) + ・通常時: 白色で表示する + +2-2. 残り時間による表示変化 + ・残り30秒以下: 文字色が濃い赤(#8B0000)に変わる + ・残り10秒以下: 1秒間隔で点滅する(opacity 1 ↔ 0.35) + + +3. HPゲージ (HP Gauge) +------------------------------------------------------------------------ + +3-1. 表示仕様 + ・位置: 画面左側 + ・形式: 「HP: 」に続いてハートアイコンで被弾状況を表示する + ・ハート表示: リスポーンまでの残り被弾可能回数をハートで示す + - 被弾していないハート: 塗りつぶしハート + - 被弾済みハート: 空ハート + ・最大表示数: 5個(PLAYER_RESPAWN_HIT_COUNT に対応) + + +4. チーム塗り率パネル (Team Paint Rate Panel) +------------------------------------------------------------------------ + +4-1. 表示仕様 + ・位置: 画面右上(ミニマップの右隣) + ・表示内容: 4チーム分の塗り面積率(%)をチームカラーの四角アイコン付きで表示する + ・形式: 「■ XX%」(■はチームカラー,XXは小数点以下切り捨ての整数) + +4-2. 残り時間による表示変化 + ・残り30秒以下: 全チームの塗り率が「???%」に置き換わり,非表示になる + + +5. ミニマップ (Mini Map) +------------------------------------------------------------------------ + +5-1. 表示仕様 + ・位置: 画面右上 + ・表示方式: Canvas要素によるリアルタイム描画 + ・表示内容: + - フィールド全体の塗り状況(チームカラーで色分け) + - 自プレイヤーの現在位置(マーカー表示) + ・トグル: タップで開閉を切り替えられる + + +6. ジョイスティック (Joystick) +------------------------------------------------------------------------ + +6-1. 表示仕様 + ・位置: 画面左側の入力領域 + ・表示: タッチ開始時にジョイスティックのベースとノブが表示される + ・ベース: 半透明の円形背景 + ・ノブ: 指の位置に追従する小さな円 + +6-2. 操作仕様 + ・タッチ開始: 指を置いた位置にジョイスティックが出現する + ・ドラッグ: 指の移動方向と距離に応じて移動入力ベクトルが決定される + ・ベクトル正規化: 入力ベクトルの長さが1.0を超える場合は1.0に正規化する + ・タッチ終了: ジョイスティックが非表示になり,移動入力がゼロになる + + +7. ボムボタン (Bomb Button) +------------------------------------------------------------------------ + +7-1. 表示仕様 + ・位置: 画面右側の入力領域 + ・表示: ボムアイコン付きの円形ボタン + ・クールダウンリング: ボタン外周にクールダウンの残り時間をリング状に表示する + - クールダウン中: リングが徐々に減っていく + - クールダウン完了: リングが消え,ボタンが活性化する + +7-2. 操作仕様 + ・タップ: ボムを現在地に設置する + ・クールダウン中: ボタンは非活性状態でタップしても反応しない + ・クールダウン時間: + - 通常時: 4000ms + - フィーバータイム時: 2000ms + + +8. 開始カウントダウン (Start Countdown) +------------------------------------------------------------------------ + +8-1. 表示仕様 + ・位置: 画面中央 + ・表示: ゲーム開始前のカウントダウン数字(3,2,1)を大きく表示する + ・ゲーム開始後: 自動的に非表示になる + + +9. 通知テキスト (Notification Text) +------------------------------------------------------------------------ + +9-1. フィーバータイム通知 + ・表示条件: ゲーム残り時間がちょうど60秒の時点で表示する + ・表示内容: 「!Fever Tieme!」 + ・位置: 画面中央 + ・演出: パルスアニメーション(拡大縮小)で表示する + +9-2. ハリケーン警告 + ・表示条件: ハリケーン出現時(残り120秒の時点)に表示する + ・表示内容: 「WARNING:ハリケーン出現」 + ・位置: 画面中央 + ・演出: 点滅アニメーションで表示する + + +10. PixiJS描画要素 (PixiJS Rendered Elements) +------------------------------------------------------------------------ + +10-1. マップ + ・各セルをチームカラーで塗りつぶした矩形で描画する + ・未塗装セルは既定の背景色で表示する + ・ビューポートカリング: 画面外のセルは描画をスキップする + +10-2. プレイヤー + ・スプライト画像で描画する + ・名前テキストをスプライト上部に表示する + ・被弾時: 点滅エフェクトを表示する + ・リスポーン時: 爆発エフェクトを表示する + +10-3. ボム + ・スプライト画像で描画する + ・爆発時: 円形の爆発エフェクトをチームカラーで表示する + +10-4. ハリケーン + ・SVGベースのオーバーレイで描画する + ・回転アニメーション付きで表示する diff --git "a/docs/04_SPEC/SPEC_05_\343\203\252\343\202\266\343\203\253\343\203\210\344\273\225\346\247\230.txt" "b/docs/04_SPEC/SPEC_05_\343\203\252\343\202\266\343\203\253\343\203\210\344\273\225\346\247\230.txt" new file mode 100644 index 0000000..5ad247e --- /dev/null +++ "b/docs/04_SPEC/SPEC_05_\343\203\252\343\202\266\343\203\253\343\203\210\344\273\225\346\247\230.txt" @@ -0,0 +1,72 @@ +======================================================================== +リザルト仕様 (Result Screen Specification) +======================================================================== + + +1. 画面遷移 (Screen Flow) +------------------------------------------------------------------------ + +1-1. 遷移タイミング + ・ゲーム終了後,サーバーからゲーム結果データを受信した時点で自動遷移する + ・結果データの受信前は「結果を読み込み中...」を表示する + +1-2. リザルト表示の段階 + 1. 初期状態: 背景演出 +「結果発表」タイトル +「Tap To Result」ガイドを表示する + 2. タップ後: タブバーと順位テーブルが表示される + + +2. 背景演出 (Background Effect) +------------------------------------------------------------------------ + +2-1. マップ表示 + ・ゲーム最終盤面のグリッドをセルごとにチームカラーで描画する + ・未塗装セルは既定の背景色で表示する + ・1位チームのカラーがタイトルテキストの装飾色に使用される + +2-2. オーバーレイ + ・背景の上に暗色の半透明オーバーレイを重ね,テキストの視認性を確保する + + +3. タブ構成 (Tab Structure) +------------------------------------------------------------------------ + +3-1. タブ一覧 + リザルト画面は3つのタブで構成される. + + ■ チーム順位タブ + ・アイコン: トロフィー + ・表示内容: チーム別の順位と塗り面積率 + ・データ: 順位,チーム名,塗り面積率(小数点第1位まで表示) + ・既定で選択されるタブ + + ■ 塗り回数タブ + ・アイコン: パレット + ・表示内容: プレイヤー個人の塗りセル数ランキング + ・データ: プレイヤー名,チーム名,塗り回数 + ・塗り回数の降順でソートされる + + ■ ヒット数タブ + ・アイコン: ボム + ・表示内容: プレイヤー個人のボムヒット数ランキング + ・データ: プレイヤー名,チーム名,ヒット数 + ・ヒット数の降順でソートされる + + +4. アクションバー (Action Bar) +------------------------------------------------------------------------ + +4-1. 表示条件 + ・タブバーと同時に表示される(タップ後) + +4-2. ボタン + ・「タイトルへ戻る」ボタン: タイトル画面に遷移する + ・「マップを見る」ボタン: 背景のマップ表示を拡大プレビューする + + +5. 結果データ仕様 (Result Data) +------------------------------------------------------------------------ + +5-1. サーバーから受信するデータ + ・rankings: チーム別の順位データ(順位,チームID,塗り面積率) + ・playerStats: プレイヤー別の成績データ(プレイヤー名,チームID,塗り回数,ボムヒット数) + ・finalGridColors: ゲーム終了時点のグリッド全セルのチームID配列 diff --git "a/docs/04_Spec/SPEC_03_\343\203\227\343\203\255\343\203\210\343\202\277\343\202\244\343\203\227_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210.txt" "b/docs/04_Spec/SPEC_03_\343\203\227\343\203\255\343\203\210\343\202\277\343\202\244\343\203\227_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210.txt" deleted file mode 100644 index b4400cd..0000000 --- "a/docs/04_Spec/SPEC_03_\343\203\227\343\203\255\343\203\210\343\202\277\343\202\244\343\203\227_\347\247\273\345\213\225\343\203\206\343\202\271\343\203\210.txt" +++ /dev/null @@ -1,107 +0,0 @@ -======================================================================== -プロトタイプ仕様書:50人同時移動テスト (Prototype Spec: Movement Test) -======================================================================== - - -1. プロトタイプ概要 (Overview) ------------------------------------------------------------------------- - -1-0. 目的 - 50人のプレイヤーが同じフィールド上で遅延なく移動できる通信基盤を検証する. - 衝突判定,塗り処理,ゲーム進行管理などの付随要素は実装せず,純粋な「移動同期」と「負荷検証」にフォーカスする. - -1-1. 検証範囲 - ・マップ: 100×100マスのグリッドマップ - ・人数: 最大50クライアント同時接続 - ・動作: 360度移動,カメラ追従,他者位置の同期表示 - - -2. クライアント実装仕様 (Client Implementation) ------------------------------------------------------------------------- - -2-0. 目的 - 入力処理,移動計算,および描画の基本ロジックを定義する. - -2-1. 入力・操作系 - ■ ジョイスティック操作 - ・左側エリア: 画面左半分をタッチ可能な移動ジョイスティック領域とする. - ・入力形式: 360°全方位入力. - ・ベクトル正規化: - - 入力ベクトルの長さが1.0を超える場合,1.0に正規化する. - - これにより,斜め移動時の意図しない加速を防止する. - - ■ 誤操作防止 (UX Protection) - ・スクリーンロック: - - ゲーム画面に対するスクロール,拡大縮小(ピンチ操作)を無効化する. - ・エッジデッドゾーン: - - 画面左右の端(10px〜)を入力無効領域とし,OSのジェスチャー機能暴発を防ぐ. - -2-2. 移動・演算ロジック - ■ キャラクター仕様 - ・サイズ: 0.8マス×0.8マス - ・移動速度: 秒速4〜5マス - - ■ 時間管理 (Time Management) - ・DeltaTime対応: - - 毎フレームの移動量計算に「前フレームからの経過時間 (DeltaTime)」を乗算する. - - 計算式: `Position += Velocity * Speed * DeltaTime` - - 目的: 端末のフレームレート(30fps/60fps/120fps)に依存せず,移動速度を一定に保つ. - - ■ 座標管理 - ・内部座標(計算・通信用): - - Float(浮動小数点)で管理し,滑らかな移動を実現する. - ・グリッド座標(表示目安): - - 内部座標の小数点以下を切り捨て(Floor)た値を現在のマスとする. - -2-3. カメラシステム (Camera System) - ■ カメラ追従 (Camera Follow) - ・挙動: - - 常に「自キャラクター」が画面の中央に配置されるよう,カメラ座標を毎フレーム更新する. - - マップ端に到達した場合のクランプ(固定)処理は,本プロトタイプでは実装不要とする(黒背景が見えても良い). - - -3. 通信アーキテクチャ (Network Architecture) ------------------------------------------------------------------------- - -3-0. 目的 - 50人の座標をリアルタイムに同期するためのデータ構造と通信フローを定義する. - -3-1. 通信フローと役割分担 - | カテゴリ | クライアント (Client) | サーバー (Server) | - | :--- | :--- | :--- | - | **自キャラ** | **予測 (Prediction)**: 入力を即時反映し座標を更新・送信. | **中継 (Relay)**: 受信座標を正とし,他者へブロードキャスト. | - | **他キャラ** | **補間 (Interpolation)**: 受信した過去の座標間を滑らかに補間移動. | **間引き (AoI)**: 距離に応じ送信情報を圧縮・除外. | - -3-2. サーバー更新ループ (Server Loop) - ■ ティックレート (Tick Rate) - ・頻度: 20Hz(50ms間隔) - ・処理内容: - 1. 受信バッファ内の全クライアントからの入力を取り出す. - 2. AoI(関心領域)判定を行い,各クライアントに必要なデータをフィルタリングする. - 3. 全クライアントへ「スナップショット」を一斉送信する. - - ■ スナップショット送信 (Snapshot) - ・送信データ: - - 視界範囲内にいる全キャラクターの ID,座標,向き. - - サーバータイムスタンプ(補間計算用). - -3-3. データ構造・最適化 - ■ パケット設計 - ・形式: バイナリパケット(ArrayBuffer等)を採用し,JSON等のテキスト形式は使用しない. - - ■ 座標の量子化 (Quantization) - ・目的: 通信帯域の削減. - ・手法: - - Float座標(0.0〜100.0)を,Unsigned Short(0〜65535)の整数値に変換して送信する. - - 受信側で再度Floatに戻して使用する. - - ■ 送信データ (Input Data) - クライアントからサーバーへ毎フレーム(または間引き)送信するデータ. - ・現在座標 (Position): 物理演算(DeltaTime適用)後の確定座標 (x, y). - ・移動ベクトル (Velocity): 補間予測用の補助データ. - ・角度 (Rotation): キャラクターの向き. - - ■ エリア別同期 (AoI) - ・ロジック: - - 各プレイヤーを中心とした一定範囲(例: 画面サイズの1.5倍)外にいる他プレイヤーの座標データは送信しない. - - これにより,50人全員が動いていても,各端末が受け取るデータ量を視界内のみに限定する. \ No newline at end of file diff --git "a/docs/05_TECH/TECH_01_\351\200\232\344\277\241\346\234\200\351\201\251\345\214\226.txt" "b/docs/05_TECH/TECH_01_\351\200\232\344\277\241\346\234\200\351\201\251\345\214\226.txt" new file mode 100644 index 0000000..157eabb --- /dev/null +++ "b/docs/05_TECH/TECH_01_\351\200\232\344\277\241\346\234\200\351\201\251\345\214\226.txt" @@ -0,0 +1,166 @@ +======================================================================== +通信最適化 (Network Optimization) +======================================================================== + + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-1. 目的 + 最大100人が同時接続するリアルタイム対戦ゲームにおいて,サーバー・クライアント間の通信帯域と + メッセージ数を最小化しつつ,低遅延な状態同期を実現する. + +1-2. 主要な最適化手法 + ・AOI(関心領域)フィルタリング: プレイヤーの周辺データのみ送信する + ・ティックバッチ送信: 50ms間隔で差分をまとめて1回送信する + ・座標量子化: 浮動小数点座標を丸めて帯域を削減する + ・差分同期: 前回送信値から変化した分のみ送信する + ・マップセルのグループ化: セル更新をチームIDでまとめて送信する + + +2. AOI(関心領域)フィルタリング (Area of Interest) +------------------------------------------------------------------------ + +2-1. 仕組み + フィールド全体をAOIセル(3×3グリッド単位)に分割し,各プレイヤーの周辺ウィンドウ + (横5×縦3 AOIセル = 15×9グリッド)に含まれるデータのみを送信する. + +2-2. AOIグリッド設定 + ・AOIセルサイズ: 3グリッド単位 + ・AOIウィンドウ: 横5セル × 縦3セル + +2-3. フィルタリング対象 + ・プレイヤー位置更新(UPDATE_PLAYERS) + ・ボム設置通知(BOMB_PLACED) + ・ハリケーン更新(UPDATE_HURRICANES) + +2-4. AOIセルキャッシュ + ・各ソケットごとに前回のAOIセル座標を保持する + ・プレイヤーのAOIセルが変化した場合のみウィンドウ再計算を行う + ・同一セル内の移動ではフィルタリング処理をスキップする + +2-5. プレイヤー可視性管理 + 各ソケットごとに以下のSetを保持し,AOI境界の出入りを検知する. + ・visiblePlayerIds: 現在可視のプレイヤーIDセット + ・visibleBombIds: 現在可視のボムIDセット + ・visibleHurricaneIds: 現在可視のハリケーンIDセット + + ■ 出入り検知 + ・前回不可視 → 今回可視: NEW_PLAYERイベントを発行する + ・前回可視 → 今回不可視: REMOVE_PLAYERイベントを発行する + ・継続可視のプレイヤーのみUPDATE_PLAYERSに含める + + +3. 20Hzティック&バッチ送信 (Tick-Based Batching) +------------------------------------------------------------------------ + +3-1. ティックレート + ・サーバーゲームループ: 20Hz(50ms間隔) + ・スケジュール方式: setTimeoutで次回ティック時刻を正確に計算し,setIntervalのドリフトを回避する + +3-2. バッチ処理 + 1ティックで以下の処理をまとめて実行し,結果を1回で送信する. + 1. ハリケーンの位置更新と衝突判定 + 2. Bot AIの行動決定と位置更新 + 3. マップの塗り処理と競合判定 + 4. ボムの爆発判定(Bot向け) + 5. 差分データの組み立て + +3-3. 送信メッセージ(1ティックあたり最大) + ・UPDATE_PLAYERS: 位置が変化したプレイヤーのみ + ・UPDATE_MAP_CELLS: 塗り状態が変化したセルのみ + ・UPDATE_HURRICANES: 状態が変化したハリケーンのみ + ・変化がない種別のメッセージは送信しない + + +4. 座標量子化 (Position Quantization) +------------------------------------------------------------------------ + +4-1. プレイヤー座標 + ・量子化スケール: 100(小数第2位で丸める) + ・計算式: Math.round(value × 100) / 100 + ・例: 3.14159 → 3.14 + +4-2. ハリケーン座標 + ・位置の量子化スケール: 10(小数第1位で丸める) + ・回転の量子化スケール: 4(0.25刻み) + ・プレイヤーより粗い精度で十分なため,帯域をさらに削減する + +4-3. 3層の量子化パイプライン(プレイヤー位置) + 1. クライアント送信時: 量子化後の座標が前回と同じなら送信をスキップする + 2. サーバー受信時: 受信座標を再量子化して精度を統一する + 3. サーバー送信時: 量子化後の座標で差分比較し,変化分のみ送信する + +4-4. 異常値ガード + ・NaN/Infinityの場合は0を返す + ・量子化スケールが無効(0以下)の場合は元の値をそのまま返す + + +5. 差分同期 (Delta Synchronization) +------------------------------------------------------------------------ + +5-1. 汎用デルタ抽出ユーティリティ + ・collectSyncDeltaEntries(): IDベースのスナップショット比較を行う汎用関数 + ・前回送信したスナップショットをMapで保持し,変化したエントリのみを返す + ・プレイヤー位置同期とハリケーン同期の両方で共通利用する + +5-2. プレイヤー位置の差分 + ・ソケットごとにlastSentPositionByPlayerIdを保持する + ・量子化後の座標が前回と同じプレイヤーはUPDATE_PLAYERSから除外する + ・切断プレイヤーのキャッシュは自動クリーンアップする + +5-3. UPDATE_PLAYERSのteamId省略 + ・初回接続時のCURRENT_PLAYERSでteamIdを含む完全なPlayerDataを送信する + ・以降のUPDATE_PLAYERSではid, x, yのみ送信し,teamIdを省略する + ・毎ティックのペイロードサイズを削減する + + +6. マップセルのグループ化 (Grouped Cell Updates) +------------------------------------------------------------------------ + +6-1. データ形式 + セル更新を個別のオブジェクト配列ではなく,チームIDをキーとしたグループ形式で送信する. + + ■ 変換前(個別形式) + [{ index: 5, teamId: 2 }, { index: 7, teamId: 2 }, { index: 10, teamId: 1 }] + + ■ 変換後(グループ形式: GroupedCellUpdates) + { "2": [5, 7], "1": [10] } + +6-2. 効果 + ・teamIdキーの重複を排除し,ペイロードサイズを削減する + ・セル数が多いほど圧縮効率が高くなる + +6-3. 差分のみ送信 + ・MapStoreのpendingUpdatesキューに変化セルのみを蓄積する + ・既に同じチームで塗られているセルはキューに追加しない + ・getAndClearUpdates()でキューの参照をゼロコピーで差し替える + + +7. クライアント側の送信最適化 (Client-Side Send Optimization) +------------------------------------------------------------------------ + +7-1. 位置送信の間引き + ・PlayerMoveSenderが量子化後の座標を前回送信値と比較する + ・変化がない場合は送信をスキップする + ・停止時にはforce: trueオプションで最終座標を確実に送信する + +7-2. 送信間隔 + ・PLAYER_POSITION_UPDATE_MS: 50ms間隔でゲームループから呼び出される + ・ティックレートと同期し,サーバーが処理可能な頻度に制限する + + +8. パフォーマンス計測 (Performance Monitoring) +------------------------------------------------------------------------ + +8-1. 計測項目(1秒ウィンドウ単位) + ・tickCount: ウィンドウ内のティック数 + ・avgTickMs: ティックあたりの平均処理時間 + ・maxTickMs: ピーク処理時間 + ・cpuUsagePct: ゲームロジックのCPU使用率(= totalTickMs / windowMs × 100) + ・avgPayloadBytesPerTick: ティックあたりの平均ペイロードサイズ + ・outboundBytesPerSec: 推定送信帯域(= avgPayload × playerCount × tickCount) + +8-2. 活用 + ・1秒ごとにログ出力し,ボトルネックの検知に利用する + ・ティック処理が50msを超えた場合はキャッチアップ機構が作動する diff --git "a/docs/05_TECH/TECH_02_\346\231\202\345\210\273\345\220\214\346\234\237_\343\203\251\343\202\260\345\257\276\347\255\226.txt" "b/docs/05_TECH/TECH_02_\346\231\202\345\210\273\345\220\214\346\234\237_\343\203\251\343\202\260\345\257\276\347\255\226.txt" new file mode 100644 index 0000000..cf740fd --- /dev/null +++ "b/docs/05_TECH/TECH_02_\346\231\202\345\210\273\345\220\214\346\234\237_\343\203\251\343\202\260\345\257\276\347\255\226.txt" @@ -0,0 +1,172 @@ +======================================================================== +時刻同期・ラグ対策 (Clock Synchronization & Lag Mitigation) +======================================================================== + + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-1. 目的 + 通信遅延が存在する環境で,全クライアントとサーバーが同じゲーム内時刻を共有し, + ボムの爆発タイミングなどの時間依存イベントを全端末で同時に発生させる. + +1-2. 主要な手法 + ・Ping/Pongクロック同期: RTT計測によるクライアント・サーバー間の時刻差推定 + ・EWMA平滑化: 外れ値を除去し安定したオフセットを維持する + ・適応的同期間隔: ネットワーク品質に応じて同期頻度を自動調整する + ・ボムの爆発時刻指定: 経過時間ベースでラグに依存しない爆発判定を行う + ・クライアントサイド予測: ボム設置をローカルで即座に反映する + ・ティックキャッチアップ: サーバー遅延時の連続ティック処理と暴走防止 + + +2. Ping/Pongクロック同期 (Clock Synchronization) +------------------------------------------------------------------------ + +2-1. プロトコル + 1. クライアントがPINGイベントで現在のクライアント時刻(clientTime)を送信する + 2. サーバーがPONGイベントでclientTimeとサーバー時刻(serverTime)を返す + 3. クライアントがPONG受信時刻からRTTとオフセットを算出する + +2-2. RTT・オフセット算出 + ・RTT計測: measuredRttMs = PONG受信時刻 - clientTime + ・片道遅延推定: estimatedOneWayMs = measuredRttMs / 2 + ・オフセット算出: offsetMs = serverTime - (clientTime + estimatedOneWayMs) + ・このオフセットを加算することで,クライアント時刻をサーバー時刻に変換できる + +2-3. RTT外れ値フィルタ + ・負のRTT: 棄却する(時計の巻き戻りや異常パケット) + ・1000ms超のRTT: 棄却する(ネットワーク異常として無視) + ・バリデーション失敗時はnullを返し,オフセット更新をスキップする + + +3. EWMA平滑化 (Exponential Weighted Moving Average) +------------------------------------------------------------------------ + +3-1. オフセットの平滑化 + ・アルファ値: 0.12(約8サンプル分の移動平均に相当) + ・計算式: smoothed = current × (1 - 0.12) + measured × 0.12 + ・効果: 単一のノイジーなサンプルの影響を緩和し,安定したオフセットを維持する + +3-2. RTTの平滑化 + ・アルファ値: 0.25(約4サンプル分の移動平均に相当) + ・オフセットより高いアルファ値で,ネットワーク状態の変化に素早く追従する + +3-3. ジャンプ検出 + ・しきい値: 250ms + ・前回のオフセットとの差が250msを超えるサンプルは棄却する + ・Wi-Fi切り替えやネットワーク経路変更による急激な変動を吸収する + + +4. 適応的同期間隔 (Adaptive Sync Interval) +------------------------------------------------------------------------ + +4-1. RTTに応じた同期頻度 + ・RTT ≤ 80ms(低遅延): 5000ms間隔で同期する + ・RTT ≤ 180ms(中遅延): 3000ms間隔で同期する + ・RTT > 180ms(高遅延): 2000ms間隔で同期する + ・RTT未取得(初期状態): 3000ms間隔で同期する + +4-2. 可変間隔ループ + ・setTimeoutベースで毎回次の同期間隔を再計算する + ・ネットワーク品質の変化にリアルタイムで適応する + ・低遅延環境では同期頻度を下げて不要なトラフィックを削減する + + +5. ボムの爆発時刻指定方式 (Elapsed-Time-Based Bomb Detonation) +------------------------------------------------------------------------ + +5-1. 仕組み + ボムの爆発タイミングをサーバー時刻ではなく,ゲーム開始からの経過時間で指定する. + + ■ 設置時の流れ + 1. クライアントが設置時の経過時間にBOMB_FUSE_MS(1000ms)を加算する + explodeAtElapsedMs = 現在の経過時間 + 1000 + 2. PlaceBombPayloadにexplodeAtElapsedMsを含めてサーバーに送信する + 3. サーバーがActiveBombRegistryに登録し,全クライアントにブロードキャストする + + ■ 爆発判定 + ・クライアント: 各フレームでelapsedMs >= explodeAtElapsedMsならば爆発状態に遷移する + ・サーバー: 各ティックで同条件を判定し,Bot向けの被弾判定を実行する + +5-2. ラグ耐性 + ・全端末が同じ「経過時間」で判定するため,個別の通信遅延に影響されない + ・サーバーACKを待たずにクライアントが独立して爆発を判定できる + ・Ping/Pongクロック同期により経過時間の基準が揃っている + +5-3. ボムの状態遷移 + ・armed(設置中): 設置〜爆発まで + ・exploded(爆発中): 爆発〜250ms後まで(爆発エフェクト表示期間) + ・finished(完了): エフェクト終了後,描画から除去する + + +6. ボム重複排除 (Bomb Deduplication) +------------------------------------------------------------------------ + +6-1. 重複排除キー + ・形式: "ownerPlayerId:requestId" + ・クライアントが生成するrequestIdとソケットIDの組み合わせで一意性を保証する + +6-2. TTL管理 + ・有効期間: BOMB_FUSE_MS + BOMB_DEDUP_EXTRA_TTL_MS = 1000 + 1000 = 2000ms + ・チェック時に期限切れエントリを自動クリーンアップする + ・同一キーが存在する場合はブロードキャストをスキップする + +6-3. 防止する問題 + ・パケット再送による重複設置 + ・同一ボムの複数回ブロードキャスト + ・爆発後の遅延リクエスト処理 + + +7. クライアントサイド予測 (Client-Side Prediction) +------------------------------------------------------------------------ + +7-1. ボム設置の即時反映 + サーバーの応答を待たずにボムをローカルに描画し,体感遅延を解消する. + + ■ フェーズ1: 楽観的設置 + 1. BombIdRegistryが一時ID(temp:requestId)を発行する + 2. 一時IDでボムをBombRepositoryに登録し,即座に描画する + 3. サーバーにPlaceBombPayloadを送信する + + ■ フェーズ2: ACK後の差し替え + 1. サーバーからBOMB_PLACED_ACK(bombId, requestId)を受信する + 2. requestIdから一時IDを逆引きする + 3. 一時IDのボムを削除し,正式なbombIdで再登録する + +7-2. 効果 + ・ボム設置のレスポンスが通信遅延(RTT/2)分だけ早く感じられる + ・サーバーが拒否した場合は一時ボムを削除するだけで整合性を保てる + + +8. ティックキャッチアップ (Tick Catch-Up) +------------------------------------------------------------------------ + +8-1. 遅延回復機構 + サーバーのティック処理が50msを超えた場合,遅れを回復するために連続ティックを実行する. + + ■ キャッチアップルール + ・1サイクルあたり最大3ティックまで連続処理する + ・3ティック処理後も遅延が残る場合は,次回ティック時刻を現在時刻にリセットする + ・これにより「キャッチアップスパイラル」(遅延が蓄積し続ける状態)を防止する + +8-2. スケジュール方式 + ・setTimeoutで次回ティックの正確な時刻を計算する + ・setIntervalのドリフト(累積誤差)を回避する + ・各サイクル開始時にnowMsを取得し,nextTickAtMsとの差分で判定する + + +9. マップの競合判定 (Map Contest Resolution) +------------------------------------------------------------------------ + +9-1. 問題 + 同一セルに複数チームのプレイヤーが同時に存在する場合,どのチームが塗るかが不定になる. + +9-2. 解決策 + ・各ティックで全プレイヤーのグリッド座標を1パスで収集する + ・cellTeamMap(Map)を構築する + ・同一セルに異なるチームIDが検出された場合,CONTESTED_CELL(-2)を設定する + ・CONTESTED_CELLのセルは塗り処理をスキップする + +9-3. 効果 + ・不公平な陣地獲得を防止する + ・1パスで処理が完了し,計算コストが低い diff --git "a/docs/05_TECH/TECH_03_\346\217\217\347\224\273\346\234\200\351\201\251\345\214\226.txt" "b/docs/05_TECH/TECH_03_\346\217\217\347\224\273\346\234\200\351\201\251\345\214\226.txt" new file mode 100644 index 0000000..b20a389 --- /dev/null +++ "b/docs/05_TECH/TECH_03_\346\217\217\347\224\273\346\234\200\351\201\251\345\214\226.txt" @@ -0,0 +1,210 @@ +======================================================================== +描画最適化 (Rendering Optimization) +======================================================================== + + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-1. 目的 + PixiJSによるリアルタイム描画において,大人数・大マップでも60fpsを維持するための + クライアント側の描画最適化手法をまとめる. + +1-2. 主要な最適化手法 + ・ビューポートカリング: 画面外のエンティティの描画をスキップする + ・画面外プレイヤーの間引き更新: 不可視プレイヤーのtick頻度を削減する + ・プレイヤー補間(LERP): リモートプレイヤーの位置を滑らかに補間する + ・フレームデルタクランプ: 異常なデルタタイムを制限する + ・テクスチャキャッシュ: 同一アセットの重複ロードを防止する + ・マップの差分描画: 変化セルのみを再描画する + ・Bot JITウォームアップ: ゲーム開始前にV8 JITコンパイルを促進する + + +2. ビューポートカリング (Viewport Culling) +------------------------------------------------------------------------ + +2-1. 仕組み + カメラの表示範囲外にあるエンティティのvisibleプロパティをfalseに設定し, + PixiJSの描画パイプラインから除外する. + +2-2. カリング対象 + ・プレイヤー(PlayerView) + ・ボム(BombView) + ・ハリケーン(HurricaneOverlayController) + +2-3. 判定方法 + ・円-矩形交差判定(isCircleIntersectingViewport)を使用する + ・エンティティの半径円とビューポート矩形の交差を判定する + +2-4. カリングマージン + ・ビューポートをGRID_CELL_SIZE分だけ拡張する(expandWorldViewport) + ・マージンにより画面端でのエンティティのポップイン(突然の出現)を防止する + +2-5. 遅延描画 + ・ハリケーンは可視状態に変化した瞬間のみrenderDisplayFromState()を呼び出す + ・不可視→可視の遷移時のみ再描画し,可視継続中は通常のtick更新のみ行う + + +3. 画面外プレイヤーの間引き更新 (Offscreen Update Throttling) +------------------------------------------------------------------------ + +3-1. 仕組み + 画面外のリモートプレイヤーのtick処理を6フレームに1回に間引く. + +3-2. 実装 + ・フレームカウンタ: frameCount % 6 === 0 のフレームのみ画面外プレイヤーをtickする + ・デルタタイム補正: 間引き時は deltaSeconds × 6 を渡し,位置精度を維持する + ・画面内プレイヤー: 毎フレーム通常のdeltaSecondsでtickする + +3-3. 効果 + ・画面外プレイヤーの更新コストを約1/6に削減する + ・デルタタイム補正により,画面内に戻った際の位置ずれを防止する + + +4. プレイヤー補間 (Player Interpolation) +------------------------------------------------------------------------ + +4-1. リモートプレイヤーのLERP + サーバーから受信した目標座標に向けて,フレームごとに滑らかに補間移動する. + + ■ 計算式 + newPos = currentPos + (targetPos - currentPos) × LERP_SMOOTHNESS × deltaTime + + ・LERP_SMOOTHNESS: 設定値で補間速度を制御する + ・deltaTimeを乗算し,フレームレートに依存しない一定速度の補間を実現する + +4-2. スナップ閾値 + ・現在位置と目標位置の距離がPLAYER_LERP_SNAP_THRESHOLDを下回る場合,即座に目標位置に移動する + ・微小な揺れ(ジッター)を防止する + +4-3. 効果 + ・20Hz(50ms間隔)の位置更新でも60fpsで滑らかに見える + ・サーバーからの位置が急に変わった場合もスムーズに追従する + + +5. フレームデルタクランプ (Frame Delta Clamping) +------------------------------------------------------------------------ + +5-1. 問題 + フレーム落ちやタブ非表示からの復帰時に,deltaTimeが異常に大きくなり + 物理計算の暴走(プレイヤーが瞬間移動する等)が発生する. + +5-2. 解決策 + ・resolveFrameDelta()関数でdeltaTimeの上下限を制限する + ・下限: 0(負の値やNaNを防止する) + ・上限: FRAME_DELTA_MAX_MS(設定された最大値) + +5-3. 適用範囲 + ・プレイヤーの移動計算 + ・LERP補間 + ・ボム・ハリケーンの状態更新 + ・全ての時間依存処理がこのクランプ済みデルタを使用する + + +6. テクスチャキャッシュ (Texture Caching) +------------------------------------------------------------------------ + +6-1. モジュールレベルキャッシュ + SVGアセットのテクスチャをモジュールスコープの変数にキャッシュし, + 複数のインスタンスから参照しても1回だけロードする. + + ■ キャッシュパターン + ・cachedTexture: ロード完了後のTexture参照を保持する + ・texturePromise: ロード中のPromise参照を保持する + ・初回呼び出し: Assets.load()でPromiseを生成し,texturePromiseに保存する + ・2回目以降: 既存のPromiseをawaitする(追加のフェッチは発生しない) + ・ロード完了後: cachedTextureから即座に返す + +6-2. キャッシュ対象 + ・爆発エフェクト(bakuhatueffe.svg): RespawnEffectTextureCache + ・ハリケーン(hurricane.svg): HurricaneTextureCache + ・ボム(Bomb.svg): BombViewの静的テクスチャ + +6-3. アセットプリロード + ・preloadGameStartAssets()をゲーム開始前に呼び出す + ・重いSVGアセットを事前にキャッシュし,初回出現時のフレーム落ちを防止する + ・void(fire-and-forget)で呼び出し,ゲーム開始をブロックしない + + +7. マップの差分描画 (Differential Map Rendering) +------------------------------------------------------------------------ + +7-1. セル単位の更新 + ・GameMapViewはセルごとにGraphicsオブジェクトをコンストラクタで事前確保する + ・renderCell(index, color)で変化したセルのみを再描画する + ・全セルの再描画は行わない + +7-2. 描画手順 + 1. 対象セルのGraphics.clear()で前回の描画を消去する + 2. 新しい色でGraphics.fill()を適用する + 3. 未塗装(-1)のセルは既定の背景色を使用する + +7-3. リビジョン管理 + ・GameMapModelがapplyUpdates()のたびにリビジョン番号をインクリメントする + ・ミニマップ等のUI要素はリビジョン変化時のみ再描画する + + +8. 状態変化キャッシュ (State Change Caching) +------------------------------------------------------------------------ + +8-1. ボムの描画スキップ + ・BombViewが前回描画した状態(state, color, radiusGrid)を保持する + ・状態が変化していない場合はrender()をスキップする + ・armed状態のボムは毎フレーム位置更新のみ,外観は変化しない + +8-2. ハリケーンの描画スキップ + ・半径の変化が0.0001以下の場合はスプライトサイズの更新をスキップする + ・画面外→画面内の遷移時のみrenderDisplayFromState()を実行する + +8-3. ボムの重複チェック + ・BombRepositoryがupsertBomb()時にisSameRenderPayload()で全フィールドを比較する + ・同一ペイロードの場合はオブジェクトの破棄・再生成をスキップする + + +9. ゲームループのステップ分離 (Game Loop Step Architecture) +------------------------------------------------------------------------ + +9-1. ステップ構成 + GameLoopが毎フレーム以下の4ステップを順に実行する. + + 1. InputStep: ジョイスティック入力をPlayerControllerに適用する + 2. SimulationStep: 自プレイヤーの移動 + リモートプレイヤーの補間 + カリング判定 + 3. BombStep: ボムの状態更新 + 爆発判定 + カリング適用 + 4. CameraStep: ワールドコンテナの位置を自プレイヤーに追従させる + +9-2. 設計上の利点 + ・各ステップが独立しており,個別に最適化できる + ・共有のLoopFrameContext(deltaSeconds等)で一貫した時間管理を行う + ・LoopFrameEffectsで移動状態をステップ間で受け渡す + + +10. リソース管理 (Resource Management) +------------------------------------------------------------------------ + +10-1. DisposableRegistry + ・ゲームシーンのリソース(イベントリスナー,PixiJSオブジェクト等)を登録する + ・disposeAll()で登録の逆順に破棄し,依存関係のクラッシュを防止する + ・シーン遷移時にメモリリークを防止する + +10-2. プレイヤーの遅延テクスチャロード + ・初期状態ではTexture.WHITE(1×1ピクセル)で描画を開始する + ・非同期でプレイヤー画像をロードし,完了後にスプライトのテクスチャを差し替える + ・ゲーム画面の初期表示をブロックしない + + +11. Bot JITウォームアップ (Bot JIT Warmup) +------------------------------------------------------------------------ + +11-1. 問題 + ゲーム開始直後の最初のティックでBot全員のdecide()が初めて呼ばれると, + V8エンジンのJITコンパイルが集中し,ティック処理時間がスパイクする. + +11-2. 解決策 + ・ゲーム開始前の待機時間(GAME_START_DELAY_MS: 5000ms)を利用する + ・warmUp()メソッドで全BotのbotTurnOrchestrator.decide()を1回ずつ空実行する + ・V8がホットパスを事前にコンパイルし,初回ティックのスパイクを軽減する + +11-3. ターゲット初期化の分散 + ・各Botのインデックスに応じてchooseNextTarget()の呼び出し回数を分散する + ・chainCount = (botIndex % 4) + 1 で1〜4回の初期化を割り当てる + ・全Botが同一ティックで重い計算を行うことを回避する diff --git "a/docs/06_TEST/TEST_01_\350\262\240\350\215\267\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.txt" "b/docs/06_TEST/TEST_01_\350\262\240\350\215\267\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.txt" new file mode 100644 index 0000000..77a0242 --- /dev/null +++ "b/docs/06_TEST/TEST_01_\350\262\240\350\215\267\343\203\206\343\202\271\343\203\210\344\273\225\346\247\230.txt" @@ -0,0 +1,182 @@ +======================================================================== +負荷テスト仕様 (Load Test Specification) +======================================================================== + + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-1. 目的 + 大人数同時接続時のサーバー安定性を検証する. + 実際のプレイヤーと同等の通信・ゲームプレイをシミュレートするBotを + 複数同時接続し,サーバーの処理能力と通信の健全性を確認する. + +1-2. テストツール + ・ファイル: test/load-bot.ts + ・言語: TypeScript(ts-node で直接実行) + ・通信: Socket.IO クライアント + ・設定ファイル: test/load-bot.constants.ts + ・環境変数: test/.env.local + +1-3. テスト構成 + ・1体目のBot(index=0)がオーナーとしてルームを作成し,ゲーム開始を実行する + ・残りのBotが順次参加し,ゲーム中のプレイヤー動作をシミュレートする + ・ゲーム終了通知を受信したら全Botが切断する + + ※ 環境構築・実行手順は docs/02_ENV/ENV_06_テスト操作手順.txt を参照すること + + +2. Botのシミュレーション動作 (Bot Behavior) +------------------------------------------------------------------------ + +2-1. 接続・入室 + + ■ 接続 + ・Socket.IOで指定URLに接続する + ・トランスポート: websocket, polling + ・再接続: 無効(reconnection: false) + ・タイムアウト: 10秒 + + ■ 入室 + ・接続直後にjoin-roomイベントを送信する + ・プレイヤー名: "bot-{index}"(0始まり) + ・ルームID: 定数で指定(既定: "1") + + ■ 参加タイミングの分散 + ・各Botの接続開始を JOIN_DELAY_MS(既定: 25ms)ずつずらす + ・接続スパイクによるサーバー負荷集中を回避する + +2-2. ゲーム開始 + + ■ オーナーBot(index=0)の動作 + ・接続後 START_DELAY_MS(既定: 800ms)経過後にstart-gameイベントを送信する + ・不足分はサーバー側でBot AIが補充される + + ■ 全Botの動作 + ・game-startイベント受信後にready-for-gameを送信する + ・game-startに含まれるstartTimeまで待機してからゲームプレイを開始する + ・gridCols/gridRowsを受信し,フィールドサイズを動的に更新する + +2-3. クロック同期 + + ■ Ping/Pong + ・5秒間隔でpingイベントを送信する(初回は接続直後に即時送信) + ・pong受信時にRTTを計測し,clockOffsetMsを更新する + ・計算式: clockOffsetMs = serverTime + (RTT / 2) - clientNow + + ■ game-start時の補正 + ・game-startペイロードのserverNowでclockOffsetMsを上書きする + ・ゲーム開始直前に最も正確なオフセットを取得する + + ■ 経過時間の算出 + ・getElapsedMs() = max(0, getServerNow() - gameStartTimeMs) + ・ボムの爆発判定やフィーバータイム判定に使用する + +2-4. 移動 + + ■ 移動方式 + ・MOVE_TICK_MS(既定: 50ms)間隔で位置を更新し,moveイベントを送信する + ・ランダムな角度で方向を決定し,BOT_SPEEDで直線移動する + ・フィールド端に到達したら方向をランダムに再設定する(壁反射) + + ■ ハリケーン回避 + ・ハリケーンの直径×1.5の範囲内に入った場合,逃げる方向へ移動方向を変更する + ・複数のハリケーンが近い場合,回避ベクトルを合算して逃げる方向を決定する + + ■ スタン中の動作 + ・isStunned()がtrueの間は移動とボム設置をスキップする + +2-5. ボム設置 + + ■ 設置条件 + ・BOT_CAN_PLACE_BOMBがtrueであること + ・ゲームが開始済みであること + ・スタン中でないこと + ・前回設置からクールダウン時間が経過していること + + ■ クールダウン + ・通常時: BOMB_NORMAL_COOLDOWN_MS(既定: 4000ms) + ・フィーバータイム時: BOMB_FEVER_COOLDOWN_MS(既定: 2000ms) + ・フィーバー判定: 残り時間 ≤ 60秒 + + ■ 送信データ + ・requestId: "{botIndex}-{serial}" で一意に生成する + ・x, y: Botの現在座標 + ・explodeAtElapsedMs: 現在の経過時間 + BOMB_FUSE_MS + + ■ 設置タイミング + ・移動tickのたびに設置条件を判定し,条件を満たせば即座に設置する + +2-6. 被弾・リスポーン + + ■ 爆弾の被弾判定 + ・他プレイヤーのbomb-placedイベントを受信し,trackedBombsに登録する + ・100ms間隔で爆発時刻に達したボムを走査する + ・爆発範囲(BOMB_RADIUS_GRID + PLAYER_RADIUS)内にいれば被弾処理を実行する + ・自チームのボムは友軍撃ちとして無視する(ownerTeamId === myTeamId) + + ■ 被弾処理(爆弾・ハリケーン共通) + ・hitCountを1増加させる + ・5回未満: PLAYER_HIT_STUN_MS(既定: 1000ms)のスタンを適用する + ・5回到達: リスポーンを実行する + - hitCountを0にリセットする + - PLAYER_RESPAWN_STUN_MS(既定: 2000ms)のスタンを適用する + - スタン明け後の次回tickMoveで初期スポーン座標に戻る + + ■ 爆弾の被弾報告 + ・被弾と判定した場合,bomb-hit-reportイベント(bombId)をサーバーに送信する + ・サーバーはplayer-hitを被弾者以外に送信するため,自分のhitCountはクライアント側で管理する + + ■ ハリケーン被弾 + ・hurricane-hitイベントで自分のplayerIdが含まれていれば被弾処理を実行する + +2-7. ゲーム終了 + + ■ 終了処理 + ・game-endまたはgame-resultイベントを受信したら以下を実行する + - gameEndedフラグをtrueに設定する + - 全タイマー(移動・Ping・ボム判定)を停止する + - ソケットを切断する + + +3. 統計収集 (Statistics) +------------------------------------------------------------------------ + +3-1. 収集項目 + ・connected: 接続成功数 + ・joined: ルーム参加数 + ・startSent: ゲーム開始リクエスト送信数 + ・moveSent: 移動イベント送信数 + ・disconnects: 切断数 + ・errors: 接続エラー数 + ・gameStarts: ゲーム開始通知受信数 + +3-2. 出力タイミング + ・テスト開始時: 設定値一覧を標準出力する + ・テスト終了時: 最終統計を標準出力する + + +4. 確認観点 (Verification Points) +------------------------------------------------------------------------ + +4-1. サーバー安定性 + ・指定Bot数での同時接続中にサーバーがクラッシュしないこと + ・全Botが正常にルーム参加・ゲーム開始できること + ・ゲーム終了まで切断エラーが発生しないこと + +4-2. パフォーマンス + ・サーバーのティック処理時間が50ms以内に収まること + - サーバーログの avgTickMs / maxTickMs を確認する + ・CPU使用率(cpuUsagePct)が許容範囲内であること + ・推定送信帯域(outboundBytesPerSec)が過大でないこと + +4-3. ゲームプレイの正常性 + ・Botの移動座標がサーバーに正しく同期されること + ・ボムの設置・爆発が正常に処理されること + ・被弾・リスポーンが正常に動作すること + ・ハリケーンの出現・被弾が正常に処理されること + +4-4. 段階的テスト + ・少数(4〜8体)から開始し,段階的にBot数を増やすこと + ・各段階でサーバーログを確認してからBot数を引き上げる + ・本番サーバーに対して実施する場合は管理者へ事前連絡すること