diff --git a/README.md b/README.md index 4812114..8ad1338 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # SkillSemiWebGame + +設定値(config)の配置ルールと定数一覧は [packages/shared/src/config/README.md](packages/shared/src/config/README.md) を参照してください。 diff --git a/apps/client/src/config/index.ts b/apps/client/src/config/index.ts new file mode 100644 index 0000000..3ec6399 --- /dev/null +++ b/apps/client/src/config/index.ts @@ -0,0 +1,48 @@ +import { config as sharedConfig } from "@repo/shared"; + +const CLIENT_GAME_CONFIG = { + TIMER_DISPLAY_UPDATE_MS: 250, + JOIN_REQUEST_TIMEOUT_MS: 8000, + + PLAYER_LERP_SMOOTHNESS: 18, + PLAYER_LERP_SNAP_THRESHOLD: 0.005, + + GRID_CELL_SIZE: 100, + + TEAM_COLORS: ["#FF4B4B", "#4B4BFF", "#4BFF4B", "#FFD700"], + + MAP_BG_COLOR: 0x111111, + MAP_GRID_COLOR: 0x333333, + MAP_BORDER_COLOR: 0xff4444, +} as const; + +const GAME_CONFIG = { + ...sharedConfig.GAME_CONFIG, + ...CLIENT_GAME_CONFIG, + get MAP_WIDTH_PX(): number { + return this.GRID_COLS * this.GRID_CELL_SIZE; + }, + get MAP_HEIGHT_PX(): number { + return this.GRID_ROWS * this.GRID_CELL_SIZE; + }, + get PLAYER_RADIUS_PX(): number { + return this.PLAYER_RADIUS * this.GRID_CELL_SIZE; + }, +} as const; + +const NETWORK_CONFIG = { + DEV_SERVER_HOST: "http://localhost", + DEV_SERVER_PORT: 3000, + get DEV_SERVER_URL() { + return `${this.DEV_SERVER_HOST}:${this.DEV_SERVER_PORT}`; + }, + PROD_SERVER_URL: "https://skillsemiwebgame.onrender.com", + SOCKET_TRANSPORTS: ["websocket", "polling"], + SOCKET_IO_PATH: sharedConfig.NETWORK_CONFIG.SOCKET_IO_PATH, +} as const; + +export const config = { + ...sharedConfig, + GAME_CONFIG, + NETWORK_CONFIG, +} as const; diff --git a/apps/client/src/hooks/useAppFlow.ts b/apps/client/src/hooks/useAppFlow.ts index 12aa756..01aa243 100644 --- a/apps/client/src/hooks/useAppFlow.ts +++ b/apps/client/src/hooks/useAppFlow.ts @@ -5,7 +5,8 @@ */ import { useCallback, useReducer, useRef, useState } from "react"; import { socketManager } from "@client/network/SocketManager"; -import { appConsts, config } from "@repo/shared"; +import { appConsts } from "@repo/shared"; +import { config } from "@client/config"; import type { appTypes, roomTypes, GameResultPayload } from "@repo/shared"; import { useSocketSubscriptions } from "./useSocketSubscriptions"; diff --git a/apps/client/src/network/SocketManager.ts b/apps/client/src/network/SocketManager.ts index f22bea7..bb8162a 100644 --- a/apps/client/src/network/SocketManager.ts +++ b/apps/client/src/network/SocketManager.ts @@ -1,5 +1,5 @@ import { io, Socket } from "socket.io-client"; -import { config } from "@repo/shared"; +import { config } from "@client/config"; import { createCommonHandler, type CommonHandler } from "./handlers/CommonHandler"; import { createTitleHandler, type TitleHandler } from "./handlers/TitleHandler"; import { createLobbyHandler, type LobbyHandler } from "./handlers/LobbyHandler"; diff --git a/apps/client/src/scenes/game/application/BombManager.ts b/apps/client/src/scenes/game/application/BombManager.ts index 08a923c..0d1c8f4 100644 --- a/apps/client/src/scenes/game/application/BombManager.ts +++ b/apps/client/src/scenes/game/application/BombManager.ts @@ -4,7 +4,7 @@ * クールダウンと設置位置解決をまとめて扱う */ import type { Container } from "pixi.js"; -import { config } from "@repo/shared"; +import { config } from "@client/config"; import { LocalPlayerController } from "@client/scenes/game/entities/player/PlayerController"; import { BombController } from "@client/scenes/game/entities/bomb/BombController"; import type { GamePlayers } from "./game.types"; diff --git a/apps/client/src/scenes/game/application/GameTimer.ts b/apps/client/src/scenes/game/application/GameTimer.ts index 1670150..7a63c81 100644 --- a/apps/client/src/scenes/game/application/GameTimer.ts +++ b/apps/client/src/scenes/game/application/GameTimer.ts @@ -3,7 +3,7 @@ * ゲーム開始時刻を基準に残り時間を計算する * 表示用の残り秒数取得を提供する */ -import { config } from "@repo/shared"; +import { config } from "@client/config"; /** 現在時刻ミリ秒を返す関数型 */ export type NowMsProvider = () => number; diff --git a/apps/client/src/scenes/game/application/loopSteps/SimulationStep.ts b/apps/client/src/scenes/game/application/loopSteps/SimulationStep.ts index fc357ed..750a396 100644 --- a/apps/client/src/scenes/game/application/loopSteps/SimulationStep.ts +++ b/apps/client/src/scenes/game/application/loopSteps/SimulationStep.ts @@ -3,7 +3,7 @@ * ゲームループのシミュレーション段を担う * ローカル更新とリモート補間更新を順に実行する */ -import { config } from "@repo/shared"; +import { config } from "@client/config"; import { socketManager } from "@client/network/SocketManager"; import { LocalPlayerController, RemotePlayerController } from "@client/scenes/game/entities/player/PlayerController"; import type { GamePlayers } from "../game.types"; diff --git a/apps/client/src/scenes/game/entities/bomb/BombView.ts b/apps/client/src/scenes/game/entities/bomb/BombView.ts index 7021e18..020f29e 100644 --- a/apps/client/src/scenes/game/entities/bomb/BombView.ts +++ b/apps/client/src/scenes/game/entities/bomb/BombView.ts @@ -4,7 +4,7 @@ * 設置中の見た目と爆風円の表示を管理する */ import { Container, Graphics } from "pixi.js"; -import { config } from "@repo/shared"; +import { config } from "@client/config"; import type { BombState } from "./BombModel"; /** 爆弾の描画表現を管理するビュー */ diff --git a/apps/client/src/scenes/game/entities/map/GameMapModel.ts b/apps/client/src/scenes/game/entities/map/GameMapModel.ts index 305f14d..75b490e 100644 --- a/apps/client/src/scenes/game/entities/map/GameMapModel.ts +++ b/apps/client/src/scenes/game/entities/map/GameMapModel.ts @@ -3,7 +3,7 @@ * マップセルの色状態を管理する計算モデル * 全体更新と差分更新を適用して描画入力用の状態を保持する */ -import { config } from '@repo/shared'; +import { config } from '@client/config'; import type { gridMapTypes } from '@repo/shared'; /** マップセル状態の計算責務を担うモデル */ diff --git a/apps/client/src/scenes/game/entities/map/GameMapView.ts b/apps/client/src/scenes/game/entities/map/GameMapView.ts index c065a25..16ae70b 100644 --- a/apps/client/src/scenes/game/entities/map/GameMapView.ts +++ b/apps/client/src/scenes/game/entities/map/GameMapView.ts @@ -4,7 +4,7 @@ * 計算済みセル状態を受けてPixi描画へ反映する */ import { Container, Graphics } from 'pixi.js'; -import { config } from '@repo/shared'; +import { config } from '@client/config'; /** マップ描画責務を担うビュー */ export class GameMapView { diff --git a/apps/client/src/scenes/game/entities/player/PlayerModel.ts b/apps/client/src/scenes/game/entities/player/PlayerModel.ts index d42e4c8..6f2709d 100644 --- a/apps/client/src/scenes/game/entities/player/PlayerModel.ts +++ b/apps/client/src/scenes/game/entities/player/PlayerModel.ts @@ -3,7 +3,7 @@ * プレイヤーの座標計算と補間計算を担うモデル * ローカル移動,リモート目標座標,送信スナップショットを管理する */ -import { config } from '@repo/shared'; +import { config } from '@client/config'; import type { playerTypes } from '@repo/shared'; /** プレイヤーの座標計算と補間計算を管理するモデル */ diff --git a/apps/client/src/scenes/game/entities/player/PlayerView.ts b/apps/client/src/scenes/game/entities/player/PlayerView.ts index 24ed39d..9c55c23 100644 --- a/apps/client/src/scenes/game/entities/player/PlayerView.ts +++ b/apps/client/src/scenes/game/entities/player/PlayerView.ts @@ -4,7 +4,7 @@ * Pixi Spriteの生成と座標反映を行う */ import { Assets, Sprite, Texture } from "pixi.js"; -import { config } from "@repo/shared"; +import { config } from "@client/config"; export class PlayerView { public readonly displayObject: Sprite; diff --git a/apps/client/src/scenes/game/hooks/useGameSceneController.ts b/apps/client/src/scenes/game/hooks/useGameSceneController.ts index fe97d0b..bc060f1 100644 --- a/apps/client/src/scenes/game/hooks/useGameSceneController.ts +++ b/apps/client/src/scenes/game/hooks/useGameSceneController.ts @@ -4,7 +4,7 @@ * Pixi描画領域,残り時間表示,入力橋渡しを提供する */ import { useCallback, useEffect, useRef, useState } from "react"; -import { config } from "@repo/shared"; +import { config } from "@client/config"; import { GameInputManager } from "@client/scenes/game/GameInputManager"; import { GameManager } from "@client/scenes/game/GameManager"; diff --git a/apps/client/vite.config.ts b/apps/client/vite.config.ts index 6af4a54..2828efe 100644 --- a/apps/client/vite.config.ts +++ b/apps/client/vite.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from 'vite' import path from 'node:path' import react from '@vitejs/plugin-react' -import { config } from '@repo/shared' +import { config } from './src/config/index.ts' export default defineConfig(({ mode }) => { const isProd = mode === 'production' diff --git a/apps/server/src/config/index.ts b/apps/server/src/config/index.ts new file mode 100644 index 0000000..fa86999 --- /dev/null +++ b/apps/server/src/config/index.ts @@ -0,0 +1,18 @@ +import { config as sharedConfig } from "@repo/shared"; + +const GAME_CONFIG = { + ...sharedConfig.GAME_CONFIG, + MAX_PLAYERS_PER_ROOM: 100, +} as const; + +const NETWORK_CONFIG = { + DEV_SERVER_PORT: 3000, + CORS_ORIGIN: "*", + CORS_METHODS: ["GET", "POST"], +} as const; + +export const config = { + ...sharedConfig, + GAME_CONFIG, + NETWORK_CONFIG, +} as const; diff --git a/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts b/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts index b4c0e61..748d349 100644 --- a/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts +++ b/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts @@ -2,7 +2,7 @@ * GameSessionLifecycleService * ゲームセッションの開始,参照,終了時クリーンアップを管理する */ -import { config } from "@repo/shared"; +import { config } from "@server/config"; import type { gameTypes, GameResultPayload } from "@repo/shared"; import { logEvent } from "@server/logging/logger"; import { gameDomainLogEvents, logResults, logScopes } from "@server/logging/index"; diff --git a/apps/server/src/domains/game/application/services/TeamAssignmentService.ts b/apps/server/src/domains/game/application/services/TeamAssignmentService.ts index fe9c33b..22c9b56 100644 --- a/apps/server/src/domains/game/application/services/TeamAssignmentService.ts +++ b/apps/server/src/domains/game/application/services/TeamAssignmentService.ts @@ -2,7 +2,7 @@ * TeamAssignmentService * プレイヤーのチーム割り当てロジックを提供するサービス */ -import { config } from "@repo/shared"; +import { config } from "@server/config"; import type { Player } from "../../entities/player/Player.js"; export class TeamAssignmentService { diff --git a/apps/server/src/domains/game/application/services/gameResultCalculator.ts b/apps/server/src/domains/game/application/services/gameResultCalculator.ts index 0117fde..ac6bdcf 100644 --- a/apps/server/src/domains/game/application/services/gameResultCalculator.ts +++ b/apps/server/src/domains/game/application/services/gameResultCalculator.ts @@ -3,7 +3,7 @@ * マップ塗り状態から最終順位ペイロードを算出する純関数を提供する * 塗り率計算,同率順位付け,チーム名解決を一箇所で扱う */ -import { config } from "@repo/shared"; +import { config } from "@server/config"; import type { GameResultPayload } from "@repo/shared"; /** グリッド色配列からゲーム結果ペイロードを生成する */ diff --git a/apps/server/src/domains/game/entities/map/mapGrid.ts b/apps/server/src/domains/game/entities/map/mapGrid.ts index f230acf..9cae240 100644 --- a/apps/server/src/domains/game/entities/map/mapGrid.ts +++ b/apps/server/src/domains/game/entities/map/mapGrid.ts @@ -2,7 +2,7 @@ * mapGrid * マップ配列の初期状態を生成する */ -import { config } from "@repo/shared"; +import { config } from "@server/config"; /** マップ全セルを未塗り状態で初期化した配列を返す */ export const createInitialGridColors = (): number[] => { diff --git a/apps/server/src/domains/game/entities/player/playerSpawn.ts b/apps/server/src/domains/game/entities/player/playerSpawn.ts index 4afc597..8c198c8 100644 --- a/apps/server/src/domains/game/entities/player/playerSpawn.ts +++ b/apps/server/src/domains/game/entities/player/playerSpawn.ts @@ -2,7 +2,7 @@ * playerSpawn * プレイヤー初期生成時のスポーン座標設定を提供する */ -import { config } from "@repo/shared"; +import { config } from "@server/config"; import { Player } from "./Player.js"; /** プレイヤーを生成し,初期スポーン座標を設定して返す */ diff --git a/apps/server/src/domains/game/loop/GameLoop.ts b/apps/server/src/domains/game/loop/GameLoop.ts index 425395b..c3a4372 100644 --- a/apps/server/src/domains/game/loop/GameLoop.ts +++ b/apps/server/src/domains/game/loop/GameLoop.ts @@ -5,7 +5,7 @@ import { Player } from "../entities/player/Player.js"; import { MapStore } from "../entities/map/MapStore"; import { getPlayerGridIndex } from "../entities/player/playerPosition.js"; -import { config } from "@repo/shared"; +import { config } from "@server/config"; import type { gameTypes } from "@repo/shared"; import { logEvent } from "@server/logging/logger"; import { gameDomainLogEvents, logResults, logScopes } from "@server/logging/index"; diff --git a/apps/server/src/domains/room/application/services/RoomJoinService.ts b/apps/server/src/domains/room/application/services/RoomJoinService.ts index 0a06116..dfaf7b8 100644 --- a/apps/server/src/domains/room/application/services/RoomJoinService.ts +++ b/apps/server/src/domains/room/application/services/RoomJoinService.ts @@ -2,7 +2,8 @@ * RoomJoinService * ルーム作成とプレイヤー参加処理を担うサービス */ -import { config, roomConsts } from "@repo/shared"; +import { roomConsts } from "@repo/shared"; +import { config } from "@server/config"; import type { roomTypes } from "@repo/shared"; import { logEvent } from "@server/logging/logger"; import { logResults, logScopes, roomDomainLogEvents } from "@server/logging/index"; diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index f7138f6..d737722 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -4,7 +4,7 @@ */ import { createHttpServer } from "./network/bootstrap/createHttpServer"; import { boot } from "./network/bootstrap/boot"; -import { config } from "@repo/shared"; +import { config } from "@server/config"; // サーバー待受ポート const PORT = process.env.PORT || config.NETWORK_CONFIG.DEV_SERVER_PORT; diff --git a/apps/server/src/network/bootstrap/createIo.ts b/apps/server/src/network/bootstrap/createIo.ts index c492f28..6ef059c 100644 --- a/apps/server/src/network/bootstrap/createIo.ts +++ b/apps/server/src/network/bootstrap/createIo.ts @@ -3,7 +3,7 @@ * 共有設定を用いてSocket.IOサーバを生成する */ import { Server } from "socket.io"; -import { config } from "@repo/shared"; +import { config } from "@server/config"; import type { Server as HttpServer } from "http"; /** CORS設定を適用したSocket.IOサーバを生成する */ diff --git a/packages/shared/src/config/README.md b/packages/shared/src/config/README.md new file mode 100644 index 0000000..bce6cce --- /dev/null +++ b/packages/shared/src/config/README.md @@ -0,0 +1,70 @@ +# Config README + +このファイルは config 定数の管理台帳です。 +配置ルール・責務境界・定数一覧はここを正とします。 + +## 配置ルール + +- shared契約(client/serverで一致が必要): [packages/shared/src/config](packages/shared/src/config) +- client表示・操作系: [apps/client/src/config/index.ts](apps/client/src/config/index.ts) +- server運用・受け入れ系: [apps/server/src/config/index.ts](apps/server/src/config/index.ts) + +## 定数一覧 + +### shared + +対象: [packages/shared/src/config/gameConfig.ts](packages/shared/src/config/gameConfig.ts), [packages/shared/src/config/networkConfig.ts](packages/shared/src/config/networkConfig.ts) + +- `GAME_CONFIG.GAME_DURATION_SEC`: 1ゲームの制限時間(秒) +- `GAME_CONFIG.PLAYER_POSITION_UPDATE_MS`: プレイヤー座標を同期送信する間隔(ms) +- `GAME_CONFIG.GRID_COLS`: マップ横方向のグリッド数 +- `GAME_CONFIG.GRID_ROWS`: マップ縦方向のグリッド数 +- `GAME_CONFIG.PLAYER_RADIUS`: プレイヤー当たり判定半径(グリッド単位) +- `GAME_CONFIG.PLAYER_SPEED`: プレイヤー移動速度(1秒あたりのグリッド移動量) +- `GAME_CONFIG.BOMB_RADIUS_GRID`: 爆風半径(グリッド単位) +- `GAME_CONFIG.BOMB_FUSE_MS`: 爆弾設置から爆発までの時間(ms) +- `GAME_CONFIG.BOMB_COOLDOWN_MS`: 次の爆弾を置けるまでの待機時間(ms) +- `GAME_CONFIG.TEAM_COUNT`: チーム総数 +- `TEAM_NAMES`: `teamId` 順の表示名配列 +- `validateTeamConfig`: チーム関連設定(件数整合性)を検証する関数 +- `assertValidTeamId`: `teamId` が有効範囲内かを検証する関数 +- `NETWORK_CONFIG.SOCKET_IO_PATH`: Socket.IO 接続パス(client/server共通契約) + +### client + +対象: [apps/client/src/config/index.ts](apps/client/src/config/index.ts) + +- `GAME_CONFIG.TIMER_DISPLAY_UPDATE_MS`: 画面の残り時間表示を更新する間隔(ms) +- `GAME_CONFIG.JOIN_REQUEST_TIMEOUT_MS`: ルーム参加要求のタイムアウト時間(ms) +- `GAME_CONFIG.PLAYER_LERP_SMOOTHNESS`: リモートプレイヤー補間の追従係数(大きいほど追従が速い) +- `GAME_CONFIG.PLAYER_LERP_SNAP_THRESHOLD`: 補間終了時に目標座標へ吸着する閾値 +- `GAME_CONFIG.GRID_CELL_SIZE`: 1グリッドの描画サイズ(px) +- `GAME_CONFIG.TEAM_COLORS`: `teamId` 順の描画色(16進カラー文字列) +- `GAME_CONFIG.MAP_BG_COLOR`: マップ背景色(Pixi用16進数) +- `GAME_CONFIG.MAP_GRID_COLOR`: グリッド線の色(Pixi用16進数) +- `GAME_CONFIG.MAP_BORDER_COLOR`: マップ外周線の色(Pixi用16進数) +- `GAME_CONFIG.MAP_WIDTH_PX` (getter): マップ横幅(`GRID_COLS * GRID_CELL_SIZE`) +- `GAME_CONFIG.MAP_HEIGHT_PX` (getter): マップ縦幅(`GRID_ROWS * GRID_CELL_SIZE`) +- `GAME_CONFIG.PLAYER_RADIUS_PX` (getter): プレイヤー半径の描画サイズ(px) +- `NETWORK_CONFIG.DEV_SERVER_HOST`: 開発環境の接続先ホスト +- `NETWORK_CONFIG.DEV_SERVER_PORT`: 開発環境の接続先ポート +- `NETWORK_CONFIG.DEV_SERVER_URL` (getter): 開発環境の接続先URL(host + port) +- `NETWORK_CONFIG.PROD_SERVER_URL`: 本番環境の接続先URL +- `NETWORK_CONFIG.SOCKET_TRANSPORTS`: Socket.IO の許可トランスポート種別 +- `NETWORK_CONFIG.SOCKET_IO_PATH`: Socket.IO 接続パス(shared契約を再利用) + +### server + +対象: [apps/server/src/config/index.ts](apps/server/src/config/index.ts) + +- `GAME_CONFIG.MAX_PLAYERS_PER_ROOM`: 1ルームに参加できる最大人数 +- `NETWORK_CONFIG.DEV_SERVER_PORT`: サーバー起動時の待受ポート(環境変数未指定時) +- `NETWORK_CONFIG.CORS_ORIGIN`: CORS で許可するオリジン +- `NETWORK_CONFIG.CORS_METHODS`: CORS で許可するHTTPメソッド + +## 追加・変更ルール + +- 変更時に client と server の同時反映が必須なら shared に追加する +- 片側のみで完結する値はその側の config に追加する +- 未使用の定数は原則削除する +- 将来利用予定で残す場合は、このREADMEに理由と予定利用箇所を追記する diff --git a/packages/shared/src/config/gameConfig.ts b/packages/shared/src/config/gameConfig.ts index 76463ce..07bfc27 100644 --- a/packages/shared/src/config/gameConfig.ts +++ b/packages/shared/src/config/gameConfig.ts @@ -5,74 +5,35 @@ */ /** ゲーム全体で利用する共有設定値 */ export const GAME_CONFIG = { - // ゲーム設定 - MAX_PLAYERS_PER_ROOM: 100, // ルーム収容人数設定 + // ゲーム進行設定(クライアント/サーバー契約) GAME_DURATION_SEC: 30, // 1ゲームの制限時間(3分 = 180秒) - // UI表示更新設定 - TIMER_DISPLAY_UPDATE_MS: 250, // 残り時間表示の更新間隔(ms) - JOIN_REQUEST_TIMEOUT_MS: 8000, // ルーム参加要求の待機タイムアウト(ms) - - // ネットワーク・描画補間設定 + // ネットワーク同期設定(クライアント/サーバー契約) PLAYER_POSITION_UPDATE_MS: 50, // 座標送信間隔(20Hz) - PLAYER_LERP_SMOOTHNESS: 18, // 補間の滑らかさ(秒基準、目安: 12〜20) - // 値を大きくすると追従が速くなるが、震えや跳ねが出やすい - // 値を小さくすると遅延感が増えるが、動きは滑らかになる - PLAYER_LERP_SNAP_THRESHOLD: 0.005, // 吸着距離閾値(グリッド単位、目安: 0.003〜0.02) - // 値を大きくすると目標に早く吸着し、停止時のブレが減るが急停止になりやすい - // 値を小さくすると吸着が遅くなり、停止時にゆらぎが残りやすい - // 画面サイズ設定 - SCREEN_WIDTH: 1280, - SCREEN_HEIGHT: 720, - - // グリッド(マス)設定 - GRID_CELL_SIZE: 100, // 1マスのサイズ(px) + // グリッド(マス)設定(クライアント/サーバー契約) GRID_COLS: 20, // 横のマス数(グリッド単位) GRID_ROWS: 20, // 縦のマス数(グリッド単位) - - // マップサイズはグリッド設定から自動計算させる(ハードコーディングを避ける) - get MAP_WIDTH_PX() { return this.GRID_COLS * this.GRID_CELL_SIZE; }, - get MAP_HEIGHT_PX() { return this.GRID_ROWS * this.GRID_CELL_SIZE; }, - // プレイヤー挙動設定(内部座標はグリッド単位) + // プレイヤー挙動設定(内部座標はグリッド単位、契約値) PLAYER_RADIUS: 0.1, // プレイヤー半径(グリッド単位、目安: 0.05〜0.2) - get PLAYER_RADIUS_PX() { return this.PLAYER_RADIUS * this.GRID_CELL_SIZE; }, PLAYER_SPEED: 3, // 1秒当たりの移動量(グリッド単位) - // 爆弾設定(内部座標はグリッド単位、時間はms) + // 爆弾設定(内部座標はグリッド単位、時間はms、契約値) BOMB_RADIUS_GRID: 1.5, // 爆風半径(グリッド単位、円形当たり判定) BOMB_FUSE_MS: 1000, // 設置から爆発までの時間(ms) BOMB_COOLDOWN_MS: 1200, // 設置後に次の爆弾を置けるまでの待機時間(ms) - // チームカラー設定 + // チーム設定(クライアント/サーバー契約) TEAM_COUNT: 4, - // teamId インデックス順カラー配列 - TEAM_COLORS: ['#FF4B4B', '#4B4BFF', '#4BFF4B', '#FFD700'], - - // プレイヤー描画・枠線設定 (新設) - PLAYER_LOCAL_STROKE_COLOR: 0xffff00, // 自プレイヤーの枠線色(黄色) - PLAYER_LOCAL_STROKE_WIDTH: 3, // 自プレイヤーの枠線の太さ - PLAYER_REMOTE_STROKE_COLOR: 0xffffff, // 他プレイヤーの枠線色(白など目立たない色) - PLAYER_REMOTE_STROKE_WIDTH: 1, // 他プレイヤーの枠線の太さ(細め) - - // マップ描画用のカラー設定 - MAP_BG_COLOR: 0x111111, // 何も塗っていないマス(背景)の色 - MAP_GRID_COLOR: 0x333333, // グリッド線の色 - MAP_BORDER_COLOR: 0xff4444, // プレイ領域外枠の色 } as const; /** teamId インデックス順のチーム名配列 */ export const TEAM_NAMES = ["赤チーム", "青チーム", "緑チーム", "黄チーム"] as const; -/** TEAM_COUNT と TEAM_COLORS の整合性を検証する */ +/** TEAM_COUNT と TEAM_NAMES の整合性を検証する */ export const validateTeamConfig = (): void => { - const { TEAM_COUNT, TEAM_COLORS } = GAME_CONFIG; - if (TEAM_COLORS.length !== TEAM_COUNT) { - throw new Error( - `GAME_CONFIG mismatch: TEAM_COLORS length (${TEAM_COLORS.length}) must equal TEAM_COUNT (${TEAM_COUNT})`, - ); - } + const { TEAM_COUNT } = GAME_CONFIG; if (TEAM_NAMES.length !== TEAM_COUNT) { throw new Error( diff --git a/packages/shared/src/config/networkConfig.ts b/packages/shared/src/config/networkConfig.ts index 88220b5..eff99b6 100644 --- a/packages/shared/src/config/networkConfig.ts +++ b/packages/shared/src/config/networkConfig.ts @@ -1,10 +1,3 @@ export const NETWORK_CONFIG = { - DEV_SERVER_HOST: "http://localhost", - DEV_SERVER_PORT: 3000, - get DEV_SERVER_URL() { return `${this.DEV_SERVER_HOST}:${this.DEV_SERVER_PORT}`; }, - PROD_SERVER_URL: "https://skillsemiwebgame.onrender.com", - SOCKET_TRANSPORTS: ["websocket", "polling"], - CORS_ORIGIN: "*", - CORS_METHODS: ["GET", "POST"], SOCKET_IO_PATH: "/socket.io", } as const; diff --git a/test/load-bot.constants.ts b/test/load-bot.constants.ts index 9be73a9..376e1fd 100644 --- a/test/load-bot.constants.ts +++ b/test/load-bot.constants.ts @@ -1,6 +1,8 @@ -import { config } from "@repo/shared"; +import { config as sharedConfig } from "@repo/shared"; +import { config as clientConfig } from "../apps/client/src/config/index.ts"; -const { GAME_CONFIG, NETWORK_CONFIG } = config; +const { GAME_CONFIG } = sharedConfig; +const { NETWORK_CONFIG } = clientConfig; export const URL = NETWORK_CONFIG.PROD_SERVER_URL; export const DEV_URL = NETWORK_CONFIG.DEV_SERVER_URL; diff --git a/test/tsconfig.json b/test/tsconfig.json index 03f4007..cc5340b 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -3,6 +3,7 @@ "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", + "allowImportingTsExtensions": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true,