import { loadGames } from '../src/content/loader'; import type { DefuseGame, Game, LabyrinthGame, StoryGame, SyncGame } from '../src/content/schemas'; import { initEngine } from '../src/engines/index'; import { createCtx } from '../src/engines/types'; import { RoomStore, type Room } from '../src/rooms/store'; export const games = loadGames(); export function getGame(id: string, engine: E): Extract { const game = games.get(id); if (!game || game.engine !== engine) throw new Error(`no ${engine} game "${id}"`); return game as Extract; } export const storyGames = [...games.values()].filter((g): g is StoryGame => g.engine === 'story'); export const defuse = () => getGame('tick-tock-together', 'defuse') as DefuseGame; export const sync = () => getGame('in-sync', 'sync') as SyncGame; export const labyrinth = () => getGame('labyrinth-of-lanterns', 'labyrinth') as LabyrinthGame; /** A room that is already in the `playing` phase for the given game. */ export function playingRoom(game: Game, startedAt = 1_000_000): Room { const { room } = new RoomStore(null).create(game.id, 'duo', startedAt); room.players[0].seat = 'A'; room.players.push({ token: 'b', seat: 'B', ready: true, viewing: null }); room.phase = 'playing'; room.startedAt = startedAt; room.engine = initEngine(game); return room; } /** A clock for tests: every call to `ctx()` is 3 seconds later, clear of the rate limit. */ export function clock(room: Room, start = 1_000_000) { let now = start; return { ctx: (advanceMs = 3000) => createCtx(room, (now += advanceMs)), get now() { return now; }, }; }