diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index dcdc17c..79adef4 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -35,6 +35,7 @@ import { getRoom, joinRoom, loadPersistedRooms, + runningRooms, addAutomaton, addChat, driveOneAutomaton, @@ -70,6 +71,11 @@ const port = Number(process.env.PORT ?? 8787); // is not reachable from the internet. Dev default stays LAN-friendly. const host = process.env.HOST ?? "0.0.0.0"; loadPersistedRooms(); +// A restart can land mid-bot-turn: without a kick, a restored room whose +// current actor is an automaton waits forever for a human to poke it. +setTimeout(() => { + for (const room of runningRooms()) runBots(room); +}, 2000); // One process serves both the built client and the websocket, so production // needs only a TLS proxy in front (or nothing, on a LAN). diff --git a/packages/server/src/rooms.ts b/packages/server/src/rooms.ts index 5b56c1e..1f88fdb 100644 --- a/packages/server/src/rooms.ts +++ b/packages/server/src/rooms.ts @@ -91,6 +91,11 @@ export function roomCount(): number { return rooms.size; } +/** Every restored, still-running room — so boot can wake their bot pumps. */ +export function runningRooms(): Room[] { + return [...rooms.values()].filter((r) => r.state && r.state.phase === "playing"); +} + export function createRoom(hostId: PlayerId): { room: Room; token: string } { const token = randomBytes(16).toString("hex"); const room: Room = {