diff --git a/apps/client/src/network/handlers/GameHandler.ts b/apps/client/src/network/handlers/GameHandler.ts index e87bf04..0360d91 100644 --- a/apps/client/src/network/handlers/GameHandler.ts +++ b/apps/client/src/network/handlers/GameHandler.ts @@ -5,7 +5,7 @@ */ import type { Socket } from "socket.io-client"; import { protocol } from "@repo/shared"; -import type { playerTypes, gridMapTypes } from "@repo/shared"; +import type { playerTypes, gridMapTypes, UpdatePlayersPayload } from "@repo/shared"; /** ゲームシーンが利用するソケット操作の契約 */ export type GameHandler = { @@ -13,8 +13,8 @@ offCurrentPlayers: (callback: (players: playerTypes.PlayerData[] | Record) => void) => void; onNewPlayer: (callback: (player: playerTypes.PlayerData) => void) => void; offNewPlayer: (callback: (player: playerTypes.PlayerData) => void) => void; - onUpdatePlayers: (callback: (players: playerTypes.PlayerData[]) => void) => void; - offUpdatePlayers: (callback: (players: playerTypes.PlayerData[]) => void) => void; + onUpdatePlayers: (callback: (players: UpdatePlayersPayload) => void) => void; + offUpdatePlayers: (callback: (players: UpdatePlayersPayload) => void) => void; onRemovePlayer: (callback: (id: string) => void) => void; offRemovePlayer: (callback: (id: string) => void) => void; onUpdateMapCells: (callback: (updates: gridMapTypes.CellUpdate[]) => void) => void; diff --git a/apps/server/src/domains/game/GameManager.ts b/apps/server/src/domains/game/GameManager.ts index c94a91b..34a577b 100644 --- a/apps/server/src/domains/game/GameManager.ts +++ b/apps/server/src/domains/game/GameManager.ts @@ -2,7 +2,7 @@ * GameManager * ゲームセッション集合の生成,更新,参照管理を統括する */ -import { type TickData } from "./loop/GameLoop"; +import type { gameTypes } from "@repo/shared"; import { Player } from "./entities/player/Player.js"; import { GameRoomSession } from "./application/services/GameRoomSession"; import { GameSessionLifecycleService } from "./application/services/GameSessionLifecycleService"; @@ -49,7 +49,7 @@ startRoomSession( roomId: string, playerIds: string[], - onTick: (data: TickData) => void, + onTick: (data: gameTypes.TickData) => void, onGameEnd: () => void ) { this.lifecycleService.startRoomSession(roomId, playerIds, onTick, onGameEnd); diff --git a/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts b/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts index 4d03233..617d04b 100644 --- a/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts +++ b/apps/server/src/domains/game/application/ports/gameUseCasePorts.ts @@ -2,15 +2,14 @@ * gameUseCasePorts * ゲーム系ユースケースが利用する入力ポートと出力ポートの契約を定義する */ -import type { TickData } from "../../loop/GameLoop"; -import type { gridMapTypes, playerTypes, roomTypes } from "@repo/shared"; +import type { gameTypes, gridMapTypes, playerTypes, roomTypes, UpdatePlayersPayload } from "@repo/shared"; /** ゲーム開始ユースケースが利用するゲーム管理入力ポート */ export interface StartGamePort { startRoomSession( roomId: string, playerIds: string[], - onTick: (data: TickData) => void, + onTick: (data: gameTypes.TickData) => void, onGameEnd: () => void ): void; getRoomStartTime(roomId: string): number | undefined; @@ -49,7 +48,7 @@ publishPongToSocket(payload: { clientTime: number; serverTime: number }): void; publishUpdatePlayersToRoom( roomId: roomTypes.Room["roomId"], - players: playerTypes.PlayerData[] + players: UpdatePlayersPayload ): void; publishMapCellUpdatesToRoom( roomId: roomTypes.Room["roomId"], diff --git a/apps/server/src/domains/game/application/services/GameRoomSession.ts b/apps/server/src/domains/game/application/services/GameRoomSession.ts index dea7e1f..efe7e8e 100644 --- a/apps/server/src/domains/game/application/services/GameRoomSession.ts +++ b/apps/server/src/domains/game/application/services/GameRoomSession.ts @@ -3,7 +3,8 @@ * 1ルーム分のゲーム進行状態とゲームループ実行を管理する */ import { logEvent } from "@server/logging/logEvent"; -import { GameLoop, type TickData } from "../../loop/GameLoop"; +import type { gameTypes } from "@repo/shared"; +import { GameLoop } from "../../loop/GameLoop"; import { Player } from "../../entities/player/Player.js"; import { MapStore } from "../../entities/map/MapStore"; import { createSpawnedPlayer } from "../../entities/player/playerSpawn.js"; @@ -31,7 +32,7 @@ public start( tickRate: number, - onTick: (data: TickData) => void, + onTick: (data: gameTypes.TickData) => void, onGameEnd: () => void ): void { if (this.gameLoop) { diff --git a/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts b/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts index 52261b6..7cc15e3 100644 --- a/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts +++ b/apps/server/src/domains/game/application/services/GameSessionLifecycleService.ts @@ -3,7 +3,7 @@ * ゲームセッションの開始,参照,終了時クリーンアップを管理する */ import { config } from "@repo/shared"; -import { type TickData } from "../../loop/GameLoop"; +import type { gameTypes } from "@repo/shared"; import { logEvent } from "@server/logging/logEvent"; import { GameRoomSession } from "./GameRoomSession"; @@ -30,7 +30,7 @@ public startRoomSession( roomId: string, playerIds: string[], - onTick: (data: TickData) => void, + onTick: (data: gameTypes.TickData) => void, onGameEnd: () => void ) { if (this.sessions.has(roomId)) { diff --git a/apps/server/src/domains/game/loop/GameLoop.ts b/apps/server/src/domains/game/loop/GameLoop.ts index e34af53..0ddb36e 100644 --- a/apps/server/src/domains/game/loop/GameLoop.ts +++ b/apps/server/src/domains/game/loop/GameLoop.ts @@ -6,21 +6,9 @@ import { MapStore } from "../entities/map/MapStore"; import { getPlayerGridIndex } from "../entities/player/playerPosition.js"; import { config } from "@repo/shared"; -import type { gridMapTypes } from "@repo/shared"; +import type { gameTypes } from "@repo/shared"; import { logEvent } from "@server/logging/logEvent"; -// コールバックで渡すデータの型定義 -/** 1ティック分のプレイヤー情報とマップ差分を表すデータ */ -export interface TickData { - playerUpdates: { - id: string; - x: number; - y: number; - teamId: number; - }[]; - cellUpdates: gridMapTypes.CellUpdate[]; -} - /** ルーム内ゲーム進行を定周期で実行するループ管理クラス */ export class GameLoop { private loopId: NodeJS.Timeout | null = null; @@ -29,14 +17,14 @@ private endMonotonicTimeMs: number = 0; private nextTickAtMs: number = 0; private readonly maxCatchUpTicks: number = 3; - private lastSentPlayers: Map = new Map(); + private lastSentPlayers: Map = new Map(); constructor( private roomId: string, private tickRate: number, private players: Map, private mapStore: MapStore, - private onTick: (data: TickData) => void, + private onTick: (data: gameTypes.TickData) => void, private onGameEnd: () => void // ゲーム終了時のコールバック ) {} @@ -103,7 +91,7 @@ } private processSingleTick(): void { - const changedPlayers: TickData["playerUpdates"] = []; + const changedPlayers: gameTypes.TickData["playerUpdates"] = []; // 1. 各プレイヤーの座標処理とマス塗りの判定 this.players.forEach((player) => { diff --git a/apps/server/src/network/handlers/game/createGameOutputAdapter.ts b/apps/server/src/network/handlers/game/createGameOutputAdapter.ts index 4e43e44..58310c4 100644 --- a/apps/server/src/network/handlers/game/createGameOutputAdapter.ts +++ b/apps/server/src/network/handlers/game/createGameOutputAdapter.ts @@ -4,7 +4,7 @@ */ import { Server } from "socket.io"; import { protocol } from "@repo/shared"; -import type { gridMapTypes, playerTypes, roomTypes } from "@repo/shared"; +import type { gridMapTypes, playerTypes, roomTypes, UpdatePlayersPayload } from "@repo/shared"; import type { GameOutputPort } from "@server/domains/game/application/ports/gameUseCasePorts"; import { createEmitToRoom } from "@server/network/adapters/socketEmitters"; import type { CommonHandlerContext } from "../CommonHandler"; @@ -14,7 +14,6 @@ type PongPayload = { clientTime: number; serverTime: number }; type GameStartPayload = { startTime: number }; type CurrentPlayersPayload = playerTypes.PlayerData[]; -type UpdatePlayersPayload = playerTypes.PlayerData[]; type MapCellUpdatesPayload = gridMapTypes.CellUpdate[]; /** ゲーム出力アダプターのインターフェース */ diff --git a/packages/shared/src/domains/game/game.type.ts b/packages/shared/src/domains/game/game.type.ts new file mode 100644 index 0000000..ed51d9f --- /dev/null +++ b/packages/shared/src/domains/game/game.type.ts @@ -0,0 +1,12 @@ +/** + * game.type + * ゲーム進行で利用する共有型を定義する + */ +import type { CellUpdate } from "../gridMap/gridMap.type"; +import type { PlayerData } from "../player/player.type"; + +/** 1ティック分のプレイヤー差分更新とマップ差分を表す共有データ */ +export interface TickData { + playerUpdates: PlayerData[]; + cellUpdates: CellUpdate[]; +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 266bcd1..48c6e17 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -2,9 +2,11 @@ export * as gridMapTypes from "./domains/gridMap/gridMap.type"; export * as gridMapLogic from "./domains/gridMap/gridMap.logic"; export * as playerTypes from "./domains/player/player.type"; +export * as gameTypes from "./domains/game/game.type"; export * as appTypes from "./domains/app/app.type"; export * as appConsts from "./domains/app/app.const"; export * as roomTypes from "./domains/room/room.type"; export * as roomConsts from "./domains/room/room.const"; export * as protocol from "./protocol/events"; +export type { UpdatePlayersPayload } from "./protocol/events"; export * as config from "./config"; \ No newline at end of file diff --git a/packages/shared/src/protocol/events.ts b/packages/shared/src/protocol/events.ts index 6082e05..28a710f 100644 --- a/packages/shared/src/protocol/events.ts +++ b/packages/shared/src/protocol/events.ts @@ -3,6 +3,8 @@ * ソケット通信で利用するイベント名定数を定義する * クライアントとサーバー間のイベント契約を共有する */ +import type { TickData } from "../domains/game/game.type"; + /** ソケットイベント名の一覧定数 */ export const SocketEvents = { // 接続・切断イベント名 @@ -31,3 +33,6 @@ PONG: "pong", // サーバーからの現在時刻レスポンス GAME_END: "game-end", // 3分経過時のゲーム終了通知 } as const; + +/** UPDATE_PLAYERS イベントで送受信するプレイヤー差分配列 */ +export type UpdatePlayersPayload = TickData["playerUpdates"];