/** * Deriving the semantic-events observation from what `window.__bmDebug.getEvents()` * returned — pure, so it is testable without a browser (settle.ts precedent). * * The input crossed a `page.evaluate` boundary from an arbitrary engine * version, so nothing about its shape is trusted: a non-array yields null * ("not observed" — older vendored engine), and malformed entries are skipped * individually rather than poisoning the run. */ /** One game event as the engine's `__bmDebug.getEvents()` projects it. */ export interface RawGameEvent { /** Gameplay-time pseudo-frame: gameplay seconds × 60. Pre-gameplay events * (menu, load) stamp 0 — the engine clock only advances while playing. */ frame: number; type: string; intensity: number; position?: [number, number, number]; actor?: string; } /** The engine's eventlog clock rate — frame / 60 = seconds of gameplay. */ export declare const GAMEPLAY_FPS = 60; /** How much early gameplay the "early" counts cover. */ export declare const EARLY_WINDOW_SECONDS = 10; /** Raw-event tail kept in the record — enough to see what happened, small * enough that result.json stays a summary rather than a transcript. */ export declare const MAX_RAW_EVENTS = 50; export interface EventsObservation { /** All events by type. */ totalByType: Record; /** * Events within the first `EARLY_WINDOW_SECONDS` of GAMEPLAY time. Frame-0 * (pre-gameplay) events land here too — acceptable, because the types * classify judges (`player-death`, `match-end`) cannot fire pre-gameplay. */ earlyByType: Record; /** Gameplay seconds of the first `match-end`, or null when none fired. */ matchEndAtSeconds: number | null; /** The last `MAX_RAW_EVENTS` events, in order. */ lastEvents: RawGameEvent[]; } export declare function deriveEventsObservation(raw: unknown): EventsObservation | null;