diff --git a/.github/images/gameplay.jpg b/.github/images/gameplay.jpg new file mode 100644 index 0000000..4e24747 --- /dev/null +++ b/.github/images/gameplay.jpg Binary files differ diff --git a/CLAUDE.md b/CLAUDE.md index 5d147f0..ce1e315 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -202,3 +202,5 @@ - 特に影響が大きいファイル: - `SPEC_03_ゲームプレイ仕様.txt`(制限時間,ボム・ハリケーン・被弾の各パラメータ) - `SPEC_04_HUD_UI仕様.txt`(表示切替のしきい値,クールダウン時間) + +設定値(config)の配置ルールと定数一覧は `packages/shared/src/config/README.md` を参照すること. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..425847a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Rinto Hasegawa, Shimoji Ryuki + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index abf5fff..08a9193 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,110 @@ -# SkillSemiWebGame +# Pixel Paint War -設定値(config)の配置ルールと定数一覧は [packages/shared/src/config/README.md](packages/shared/src/config/README.md) を参照してください。 +![タイトル画面](apps/client/public/title.png) -## クライアント環境変数(Vite) +チーム対抗のリアルタイム陣取りペイントバトルゲームです。 +最大4チームのプレイヤーがブラウザ上で同じフィールドに参加し、制限時間内に自チームの色でマスを塗りつぶして陣地を広げます。 +終了時に最も多くのセルを塗ったチームが勝利です。 -`apps/client/src/config/index.ts` の `PROD_SERVER_URL` は `import.meta.env.VITE_PROD_SERVER_URL` を参照します。 +![ゲーム画面](.github/images/gameplay.jpg) -- `VITE_PROD_SERVER_URL` はクライアント用の環境変数です(Viteビルド時に埋め込まれます)。 -- Renderでは server サービスではなく、client をビルドして配信するサービス側で設定してください。 -- 値を変更した場合は再デプロイ(再ビルド)が必要です。 -- `VITE_*` の値はブラウザから参照可能なため、秘密情報は設定しないでください。 +## 技術スタック -### Render での設定手順 +| 区分 | 技術 | +|---|---| +| フロントエンド | Vite + Preact + TypeScript | +| バックエンド | Node.js + TypeScript | +| 通信 | Socket.IO (WebSocket) | +| 描画 | Pixi.js (WebGL) | +| パッケージ管理 | pnpm workspaces (monorepo) | +| 開発環境 | Docker Dev Container | -1. Render ダッシュボードで client サービスを開く -2. `Environment` で環境変数を追加する -3. `Key`: `VITE_PROD_SERVER_URL` -4. `Value`: `https://` -5. 保存後に再デプロイする +## 開発環境のセットアップ -### ローカル開発での例 +**必要なもの**: Docker、VS Code、VS Code拡張機能「Dev Containers」 -`apps/client/.env.development` +1. リポジトリをクローンする +2. VS Codeでフォルダを開く +3. 左下の「><」アイコン →「Reopen in Container」を選択する +4. コンテナの起動を待つ(初回は数分かかります) -```env -VITE_PROD_SERVER_URL=https:// +起動後、以下のコマンドで動作確認できます。 + +```bash +# 共有パッケージのビルド +pnpm --filter @repo/shared build + +# クライアント起動(http://localhost:5173) +pnpm --filter client dev + +# サーバ起動 +pnpm --filter server dev ``` + +詳細は [ENV_04_環境構築手順書.txt](docs/02_ENV/ENV_04_環境構築手順書.txt) を参照してください。 + +## デプロイ + +クライアント(静的ファイル)とサーバ(Node.js)を別々にデプロイします。 +ビルド時に `VITE_PROD_SERVER_URL` にサーバのURLを設定する必要があります。 + +詳細は各手順書を参照してください。 + +| デプロイ先 | ドキュメント | +|---|---| +| Render | [ENV_09_Renderデプロイ手順.txt](docs/02_ENV/ENV_09_Renderデプロイ手順.txt) | +| 研究室サーバ(Nginx + Docker) | [ENV_10_研究室サーバデプロイ手順書.txt](docs/02_ENV/ENV_10_研究室サーバデプロイ手順書.txt) | +| 環境変数一覧 | [ENV_08_環境変数設定.txt](docs/02_ENV/ENV_08_環境変数設定.txt) | + +## ドキュメント + +### 開発ガイド + +| ドキュメント | 内容 | +|---|---| +| [GUIDE_01_ドキュメント作成ガイド.txt](docs/01_GUIDE/GUIDE_01_ドキュメント作成ガイド.txt) | ドキュメントの書き方・フォーマット規則 | +| [GUIDE_02_ファイル命名規則.txt](docs/01_GUIDE/GUIDE_02_ファイル命名規則.txt) | ファイル・ディレクトリの命名規則 | +| [GUIDE_03_Git運用ルール.txt](docs/01_GUIDE/GUIDE_03_Git運用ルール.txt) | ブランチ・コミットの運用ルール | +| [GUIDE_04_コードコメント規則.txt](docs/01_GUIDE/GUIDE_04_コードコメント規則.txt) | コードコメントの書き方 | +| [GUIDE_05_プロトコル追加手順.txt](docs/01_GUIDE/GUIDE_05_プロトコル追加手順.txt) | Socket.IOイベントの追加手順 | + +### 環境・構成 + +| ドキュメント | 内容 | +|---|---| +| [ENV_01_環境構築・技術スタック.txt](docs/02_ENV/ENV_01_環境構築・技術スタック.txt) | 技術スタックとプロジェクト構成 | +| [ENV_02_ディレクトリ構造.txt](docs/02_ENV/ENV_02_ディレクトリ構造.txt) | ソースコードのディレクトリ構造 | +| [ENV_04_環境構築手順書.txt](docs/02_ENV/ENV_04_環境構築手順書.txt) | 開発環境のセットアップ手順 | +| [ENV_05_Docker運用操作ガイド.txt](docs/02_ENV/ENV_05_Docker運用操作ガイド.txt) | Dockerの運用・操作コマンド | + +### 仕様 + +| ドキュメント | 内容 | +|---|---| +| [SPEC_01_ゲーム概要_画面遷移.txt](docs/04_SPEC/SPEC_01_ゲーム概要_画面遷移.txt) | ゲーム概要・画面遷移フロー | +| [SPEC_02_ロビー仕様.txt](docs/04_SPEC/SPEC_02_ロビー仕様.txt) | ロビー画面の仕様 | +| [SPEC_03_ゲームプレイ仕様.txt](docs/04_SPEC/SPEC_03_ゲームプレイ仕様.txt) | ゲームプレイの詳細仕様 | +| [SPEC_04_HUD_UI仕様.txt](docs/04_SPEC/SPEC_04_HUD_UI仕様.txt) | HUD・UIの仕様 | +| [SPEC_05_リザルト仕様.txt](docs/04_SPEC/SPEC_05_リザルト仕様.txt) | リザルト画面の仕様 | + +### 技術詳細 + +| ドキュメント | 内容 | +|---|---| +| [TECH_01_通信最適化.txt](docs/05_TECH/TECH_01_通信最適化.txt) | 通信量削減・最適化の実装方針 | +| [TECH_02_時刻同期_ラグ対策.txt](docs/05_TECH/TECH_02_時刻同期_ラグ対策.txt) | 時刻同期・ラグ補正の実装方針 | +| [TECH_03_描画最適化.txt](docs/05_TECH/TECH_03_描画最適化.txt) | 描画パフォーマンス最適化の実装方針 | + +### テスト + +| ドキュメント | 内容 | +|---|---| +| [TEST_01_負荷テスト仕様.txt](docs/06_TEST/TEST_01_負荷テスト仕様.txt) | 負荷テストの仕様・実行手順 | + +## 作者 + +Rinto Hasegawa, Shimoji Ryuki + +## ライセンス + +[MIT](LICENSE) diff --git a/apps/client/src/assets/preact.svg b/apps/client/src/assets/preact.svg deleted file mode 100644 index 908f17d..0000000 --- a/apps/client/src/assets/preact.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file 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" index 972528f..2e27b2a 100644 --- "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" @@ -8,87 +8,79 @@ ソースコード構造を定義する. プロジェクト全体の構成(設定ファイル・インフラ)については ENV_01 を参照すること. +記載粒度: 全フォルダを漏れなく記載する.ファイルはエントリーポイント(index.ts・main.tsx 等)のみ明記する. +フォルダを追加・削除・移動した場合は本ドキュメントを合わせて更新すること. + 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 # タイトル画面 + ├── main.tsx # 起動エントリ + ├── app.tsx # ルートUI + ├── components/ # 共通コンポーネント + ├── config/ # クライアント設定 + ├── hooks/ # グローバルフック + │ ├── application/ # アプリケーション層フック + │ └── types/ # フック型定義 + ├── network/ # サーバー通信層 + │ └── handlers/ # WSハンドラ・イベントブリッジ + ├── styles/ # 全体スタイル + └── scenes/ # 画面シーン群 + ├── game/ # ゲーム画面 + │ ├── application/ # ゲームアプリケーション層 + │ │ ├── assets/ # ゲームアセット管理 + │ │ ├── combat/ # 戦闘処理 + │ │ ├── culling/ # 描画カリング + │ │ ├── lifecycle/ # ライフサイクル管理 + │ │ ├── loopSteps/ # ゲームループステップ + │ │ ├── network/ # ゲームネットワーク処理 + │ │ │ ├── adapters/ # ネットワークアダプタ + │ │ │ ├── handlers/ # ネットワークハンドラ + │ │ │ └── receivers/ # 受信処理 + │ │ ├── orchestrators/ # オーケストレータ + │ │ ├── runtime/ # ランタイム管理 + │ │ ├── time/ # 時刻・タイマー管理 + │ │ └── ui/ # UI制御 + │ ├── entities/ # 描画・状態管理エンティティ + │ │ ├── bomb/ # 爆弾エンティティ + │ │ ├── hurricane/ # ハリケーンエンティティ + │ │ ├── map/ # マップエンティティ + │ │ └── player/ # プレイヤーエンティティ + │ ├── hooks/ # ゲーム画面フック + │ ├── input/ # 入力UI群 + │ │ ├── bomb/ # 爆弾ボタンUI + │ │ │ ├── hooks/ # 爆弾ボタンフック + │ │ │ └── presentation/ # 爆弾ボタン表示 + │ │ ├── hooks/ # 入力共通フック + │ │ ├── joystick/ # ジョイスティックUI + │ │ │ ├── common/ # スティック定数・型 + │ │ │ ├── hooks/ # スティック制御フック + │ │ │ ├── model/ # スティックモデル + │ │ │ └── presentation/ # スティック描画 + │ │ ├── minimap/ # ミニマップUI + │ │ │ ├── hooks/ # ミニマップフック + │ │ │ └── presentation/ # ミニマップ表示 + │ │ └── presentation/ # 入力UI共通表示 + │ ├── presentation/ # ゲームHUD + │ └── styles/ # ゲーム画面スタイル + ├── lobby/ # ロビー画面 + │ ├── components/ # ロビーUIコンポーネント + │ ├── presentation/ # ロビー表示ロジック + │ └── styles/ # ロビースタイル + ├── result/ # リザルト画面 + │ ├── components/ # リザルトUIコンポーネント + │ ├── hooks/ # リザルト画面フック + │ ├── styles/ # リザルト画面スタイル + │ └── types/ # リザルト画面型定義 + ├── shared/ # シーン間共通リソース + │ └── styles/ # シーン共通スタイル + └── title/ # タイトル画面 2-2. 設計方針 - ・scenes/ 配下にシーン単位(title, lobby, game, result)で分割する + ・scenes/ 配下にシーン単位(title,lobby,game,result)で分割する ・各シーンは MVC ベースの構成とし,entities/ に描画対象を集約する ・network/ 層がサーバーとの通信を担当し,scenes/ 内から直接 protocol を参照しない @@ -97,82 +89,55 @@ ------------------------------------------------------------------------ 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/ # ペイロード検証 + ├── index.ts # サーバー起点 + ├── application/ # アプリケーション統合層 + │ └── coordinators/ # アプリ統合制御 + ├── common/ # 共通ユーティリティ + ├── config/ # サーバー設定 + ├── logging/ # ログ出力基盤 + │ ├── constants/ # ログ定数 + │ └── contracts/ # ログ契約型 + ├── domains/ # ビジネスロジック層 + │ ├── game/ # ゲームドメイン + │ │ ├── application/ # ゲームアプリケーション層 + │ │ │ ├── ports/ # ユースケース入出力境界 + │ │ │ ├── services/ # ゲームサービス群 + │ │ │ │ └── bot/ # Bot AIシステム + │ │ │ │ ├── adapters/ # Botアダプタ + │ │ │ │ ├── combat/ # Bot戦闘行動 + │ │ │ │ ├── movement/ # Bot移動処理 + │ │ │ │ ├── orchestrators/ # Botオーケストレータ + │ │ │ │ ├── policies/ # Bot行動ポリシー + │ │ │ │ ├── roster/ # Bot管理・編成 + │ │ │ │ ├── state/ # Bot状態管理 + │ │ │ │ └── types/ # Bot型定義 + │ │ │ └── useCases/ # ゲームユースケース + │ │ ├── entities/ # ゲームエンティティ + │ │ │ ├── bomb/ # 爆弾エンティティ + │ │ │ ├── map/ # マップ状態 + │ │ │ └── player/ # プレイヤーエンティティ + │ │ └── loop/ # ゲームループ + │ │ └── hurricane/ # ハリケーン詳細処理 + │ └── room/ # ルームドメイン + │ └── application/ # ルームアプリケーション層 + │ ├── ports/ # ユースケース入出力境界 + │ ├── services/ # ルームサービス群 + │ └── useCases/ # ルームユースケース + └── network/ # Socket.IO通信層 + ├── adapters/ # 送信アダプタ群 + ├── bootstrap/ # 起動配線 + ├── handlers/ # イベントハンドラ群 + │ ├── game/ # ゲームイベントハンドラ + │ │ ├── aoi/ # 視認範囲フィルタ処理 + │ │ ├── input/ # ゲーム入力ハンドラ + │ │ ├── runtime/ # ゲームランタイム解決 + │ │ └── services/ # ゲーム同期サービス群 + │ ├── registration/ # 接続登録コンテキスト + │ └── room/ # ルームハンドラ群 + ├── types/ # ネットワーク型定義 + └── validation/ # ペイロード検証 3-2. 設計方針 ・domains/ にビジネスロジックを集約し,game/ と room/ に分離する @@ -185,47 +150,22 @@ ------------------------------------------------------------------------ 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 # ロビーイベントマップ + ├── index.ts # 共有エクスポート + ├── config/ # 共通設定・定数 + ├── domains/ # 共有ドメインロジック + │ ├── app/ # アプリ定数・型 + │ ├── game/ # ゲームドメイン共有ロジック + │ │ ├── aoi/ # 視認範囲ロジック + │ │ ├── bombHit/ # 爆弾判定ロジック + │ │ ├── gridMap/ # マップ計算・型 + │ │ ├── player/ # プレイヤー型・移動同期 + │ │ └── tick/ # ティックシステム + │ └── room/ # ルーム定数・型 + └── protocol/ # ソケットイベント定義 + ├── maps/ # イベント方向別型マップ + └── payloads/ # イベントペイロード型 4-2. 設計方針 ・client と server の両方から import される「真実の定義場所」として機能する diff --git "a/docs/02_ENV/ENV_08_\347\222\260\345\242\203\345\244\211\346\225\260\350\250\255\345\256\232.txt" "b/docs/02_ENV/ENV_08_\347\222\260\345\242\203\345\244\211\346\225\260\350\250\255\345\256\232.txt" new file mode 100644 index 0000000..3ba0860 --- /dev/null +++ "b/docs/02_ENV/ENV_08_\347\222\260\345\242\203\345\244\211\346\225\260\350\250\255\345\256\232.txt" @@ -0,0 +1,48 @@ +======================================================================== +環境変数設定 (Environment Variables) +======================================================================== + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-1. 目的 + 本ドキュメントは,Pixel Paint War のビルド・実行時に必要な環境変数の + 一覧と設定方法を記す. + デプロイ先ごとの固有手順は各デプロイ手順書を参照すること. + + ・Render へのデプロイ: ENV_09_Renderデプロイ手順.txt + ・研究室サーバへのデプロイ: ENV_10_研究室サーバデプロイ手順書.txt + + +2. クライアント環境変数(Vite) (Client Environment Variables) +------------------------------------------------------------------------ + +2-1. 変数一覧 + + ■ VITE_PROD_SERVER_URL + ・用途: 本番環境でクライアントが接続するサーバの URL + ・参照箇所: apps/client/src/config/index.ts の PROD_SERVER_URL + ・設定タイミング: Vite ビルド時に静的ファイルへ埋め込まれる + ・注意事項: + - VITE_* の値はブラウザから参照可能なため,秘密情報は設定しないこと + - 値を変更した場合は再ビルド・再デプロイが必要 + +2-2. ローカル開発での設定例 + 開発時は以下のファイルに記述する. + + ファイル: apps/client/.env.development + + VITE_PROD_SERVER_URL=http://localhost:3000 + + ※ .env.development は .gitignore に含めること + + +3. サーバ環境変数 (Server Environment Variables) +------------------------------------------------------------------------ + +3-1. 変数一覧 + + ■ NODE_ENV + ・用途: 実行環境の識別 + ・値: production(本番)/ development(開発) + ・設定箇所: docker-compose.prod.yml の environment セクション 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" deleted file mode 100644 index 6f4179d..0000000 --- "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" +++ /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/02_ENV/ENV_09_Render\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206.txt" "b/docs/02_ENV/ENV_09_Render\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206.txt" new file mode 100644 index 0000000..4d2d429 --- /dev/null +++ "b/docs/02_ENV/ENV_09_Render\343\203\207\343\203\227\343\203\255\343\202\244\346\211\213\351\240\206.txt" @@ -0,0 +1,71 @@ +======================================================================== +Render デプロイ手順 (Render Deployment Guide) +======================================================================== + +1. 概要 (Overview) +------------------------------------------------------------------------ + +1-1. 目的 + 本ドキュメントは,Pixel Paint War を Render にデプロイする手順を記す. + 環境変数の詳細については ENV_08_環境変数設定.txt を参照すること. + +1-2. 構成 + Render 上で以下の2サービスを運用する. + + ・client サービス: Vite でビルドした静的ファイルを配信 + ・server サービス: Node.js バックエンドを動作させる Web Service + + +2. 環境変数の設定 (Environment Variables) +------------------------------------------------------------------------ + +2-1. client サービスへの設定 + VITE_PROD_SERVER_URL はビルド時に埋め込まれるため, + server サービスではなく client サービス側で設定すること. + + 1. Render ダッシュボードで client サービスを開く + 2. 「Environment」タブを開く + 3. 以下の環境変数を追加する + Key: VITE_PROD_SERVER_URL + Value: https:// + 4. 保存後に「Manual Deploy」または自動デプロイで再ビルドする + + ※ 値を変更した場合は必ず再デプロイ(再ビルド)すること + + +3. デプロイ手順 (Deployment Steps) +------------------------------------------------------------------------ + +3-1. server サービスの設定 + 1. Render ダッシュボードで「New +」→「Web Service」を選択する + 2. リポジトリを接続する + 3. 以下の設定を行う + ・Environment: Node + ・Build Command: pnpm --filter @repo/shared build && pnpm --filter server build + ・Start Command: node apps/server/dist/index.js + 4. 「Create Web Service」で作成する + +3-2. client サービスの設定 + 1. Render ダッシュボードで「New +」→「Static Site」を選択する + 2. リポジトリを接続する + 3. 以下の設定を行う + ・Build Command: pnpm --filter @repo/shared build && pnpm --filter client build + ・Publish Directory: apps/client/dist + 4. 2章の手順で環境変数 VITE_PROD_SERVER_URL を設定する + 5. 「Create Static Site」で作成する + +3-3. 動作確認 + 1. server サービスのログで起動エラーがないことを確認する + 2. client サービスの URL にブラウザからアクセスしてゲーム画面を確認する + + +4. 再デプロイ手順 (Redeployment) +------------------------------------------------------------------------ + +4-1. コード変更時 + main ブランチへのマージを契機に自動デプロイが走る(Auto-Deploy 有効時). + 手動で行う場合は各サービスの「Manual Deploy」ボタンを押す. + +4-2. 環境変数変更時 + client サービスの環境変数を変更した場合は, + 変更後に必ず再デプロイ(再ビルド)を実施すること. 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" deleted file mode 100644 index e489c79..0000000 --- "a/docs/02_ENV/ENV_09_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/02_ENV/ENV_10_\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_10_\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_10_\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_11_TypeScript\346\246\202\350\246\201.txt" "b/docs/02_ENV/ENV_11_TypeScript\346\246\202\350\246\201.txt" new file mode 100644 index 0000000..e489c79 --- /dev/null +++ "b/docs/02_ENV/ENV_11_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