Game engine
Server-side game logic under server/src/game/, driven by Socket.IO handlers and persisted via services + src/data/.
Core classes
| Class | File | Role |
|---|---|---|
ForagingGame | ForagingGame.js | Foraging round state: patches, tokens, timing, erasures |
ArithmeticTest | ArithmeticTest.js | Stress-task problem generation and scoring |
BotManager | BotManager.js | Bot policies for multiplayer / simulations (POLICIES) |
GameRegistry | GameRegistry.js | In-memory maps of active single- and multiplayer games; erasure-mode helpers |
Surrounding services
| Piece | Role |
|---|---|
services/RoomService.js | Create/join experiment, friends, and solo rooms; player lifecycle |
services/foragingSaveService.js | saveSinglePlayerForaging, saveMultiplayerForaging |
data/saveSinglePlayerForagingData.js (and siblings) | Lower-level Prisma writes for SP / MP / practice / arithmetic |
utils/timerManager.js | Register/clear timers so round timers do not leak across rooms |
utils/safeArithmeticEval.js | Evaluate arithmetic expressions with a digit/+ - * / whitelist — never eval |
utils/regionPartition.js | Spatial / region helpers for foraging patches (when used by game code) |
Lifecycle (simplified)
- Client joins a room (experiment secret code, friends, or solo).
- Socket handlers mutate the in-memory game via
GameRegistry. - Round / session end triggers save services → Prisma models (
SinglePlayerForaging,MultiplayerForaging,MultiplayerForagingRound,PracticeSession,ArithmeticTest, …).
Simulations
Admin simulations reuse bot policies (BotManager) through simulationService + simulationSocket, writing SimulationRun / SimulationRound / SimulationBotResult. See the Admin docs (Phase 2) for the UI path.
Design rules
- Game timers go through
timerManager - Math answers go through
safeArithmeticEval - Socket handlers use
wrapHandler/wrapSyncHandler - Prefer services for DB writes over ad-hoc Prisma in socket files