export interface BeatClockConfig { bpm: number; /** Beats per bar/measure, for bar-relative UI (rhythm-game combo windows). Default 4. */ beatsPerBar?: number; } export interface BeatSnapshot { /** Fractional beat count since the clock started. */ beat: number; beatIndex: number; bar: number; beatInBar: number; /** 0..1 fractional position within the current beat. */ phase: number; } export interface BeatClock { /** Advance by a game-time delta (already scaled by ctx.time — never wall-clock). Returns the resulting snapshot and fires onBeat once per newly crossed integer beat. */ advance(gameDt: number): BeatSnapshot; snapshot(): BeatSnapshot; /** Elapsed game-seconds since the clock started. */ now(): number; beatDurationSec(): number; bpm(): number; } /** @internal */ export declare function createBeatClock(config: BeatClockConfig, onBeat?: (beatIndex: number) => void): BeatClock; /** Signed offset (game-seconds) from `nowSec` to the nearest beat boundary — negative = early, positive = late (#286.12). * @internal */ export declare function nearestBeatDelta(nowSec: number, beatDurationSec: number): number; export interface BeatAccuracyTier { id: string; /** Maximum absolute delta (game-seconds) from the beat that still earns this tier. */ windowSec: number; } export interface BeatJudgement { /** The matched tier id, or `"miss"` beyond every tier. */ tier: string; /** Signed delta to the nearest beat — negative = early, positive = late. */ deltaSec: number; } export declare const DEFAULT_BEAT_TIERS: readonly BeatAccuracyTier[]; /** Classify a press against the nearest beat into tiered judgements (perfect/good/miss by default). Tiers must be ordered tightest-first. * @internal */ export declare function classifyBeatAccuracy(nowSec: number, beatDurationSec: number, tiers?: readonly BeatAccuracyTier[]): BeatJudgement; /** Whether a snapshot sits inside a bar-relative open window `[fromBeat, toBeat)` — e.g. "act on beats 2-4 of every bar" (#286.12). * @internal */ export declare function inBarWindow(snapshot: BeatSnapshot, fromBeat: number, toBeat: number): boolean; /** The absolute beat-time (game-seconds) that a press at `nowSec` quantizes to: the same instant if it lands on a beat boundary, else the next one. * @internal */ export declare function nextBeatTime(nowSec: number, beatDurationSec: number, epsilon?: number): number; export interface BufferedAction { action: T; bufferedAtSec: number; fireAtSec: number; } export interface BeatInputBuffer { /** Buffer an action; it quantizes to fire on the next beat tick (or immediately if `nowSec` is already on a beat). Returns the resolved fire time. */ buffer(action: T, nowSec: number): number; /** Drain and return every action whose fire time has arrived, in the order they were buffered. */ advance(nowSec: number): T[]; pendingCount(): number; clear(): void; } /** @internal */ export declare function createBeatInputBuffer(beatDurationSec: number): BeatInputBuffer;