explodorama / files / src / sim / record.ts
record.ts
5551eb37 2026-10-20 Pavel Safronov | 1 | import { newRun } from './state' |
| 2 | import { step } from './turn' | |
d3e4ed26 2026-10-25 Pavel Safronov | 3 | import { DEFAULT_OPTIONS, type Action, type ChargeId, type GameEvent, type GameState, type RunOptions } from './types' |
5551eb37 2026-10-20 Pavel Safronov | 4 | |
| 5 | /** | |
| 6 | * Bumped whenever a rule change would make an old record replay differently. Records from | |
| 7 | * another version can't be trusted to replay (PLAN.md §11). | |
| 8 | */ | |
92cc4ee3 2026-11-02 Pavel Safronov | 9 | export const SIM_VERSION = 43 |
5551eb37 2026-10-20 Pavel Safronov | 10 | |
| 11 | /** Everything needed to reproduce a run exactly: mid-run saves, replays, certificates. */ | |
| 12 | export interface RunRecord { | |
| 13 | simVersion: number | |
| 14 | seed: number | |
| 15 | startLevel: number | |
d3e4ed26 2026-10-25 Pavel Safronov | 16 | /** The charge carried from the start (testing aid, `?charge=`; null in a normal run). */ |
| 17 | startCharge: ChargeId | null | |
beb9f2b7 2026-10-21 Pavel Safronov | 18 | /** Board size and modes, chosen when the run started. */ |
| 19 | options: RunOptions | |
5551eb37 2026-10-20 Pavel Safronov | 20 | actions: Action[] |
| 21 | } | |
| 22 | ||
d3e4ed26 2026-10-25 Pavel Safronov | 23 | export function newRecord(seed: number, startLevel = 1, startCharge: ChargeId | null = null, options: RunOptions = DEFAULT_OPTIONS): RunRecord { |
| 24 | return { simVersion: SIM_VERSION, seed, startLevel, startCharge, options: { ...options }, actions: [] } | |
5551eb37 2026-10-20 Pavel Safronov | 25 | } |
| 26 | ||
0b61e800 2026-10-23 Pavel Safronov | 27 | /** `onEvent` sees every event on the way, for the UI to rebuild what it remembers about the run. */ |
| 28 | export function replay(record: RunRecord, onEvent?: (e: GameEvent) => void): GameState { | |
d3e4ed26 2026-10-25 Pavel Safronov | 29 | let s = newRun(record.seed, record.startLevel, record.startCharge, record.options) |
0b61e800 2026-10-23 Pavel Safronov | 30 | for (const a of record.actions) { |
| 31 | const result = step(s, a) | |
| 32 | if (onEvent) result.events.forEach(onEvent) | |
| 33 | s = result.state | |
| 34 | } | |
5551eb37 2026-10-20 Pavel Safronov | 35 | return s |
| 36 | } |