@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
85 lines (76 loc) • 2.52 kB
JavaScript
import { assert } from "../../../core/assert.js";
/**
* Tracks the boundary between confirmed and speculative frames.
*
* A frame is **confirmed** if its actions have been acknowledged by the
* authoritative source (server, or remote peer in P2P) — meaning the frame
* cannot be rewound away. A frame is **speculative** if it's been predicted
* locally but not yet acked.
*
* Used for:
* - **Side-effect gating.** One-shot effects (sounds, particle bursts,
* scene transitions, brutalities) should only fire from confirmed frames;
* speculative frames may be rolled back, and re-firing the effect on
* replay produces the same audio/VFX glitch the MK X postmortem warned
* about.
* - **Garbage collection of action-log frames.** Frames at or below the
* confirmed boundary will not be rewound to, so their action records
* can be dropped from the ring once they fall out of the per-peer
* baseline window too.
*
* Implementation is intentionally trivial: a single monotonic counter.
* Frames `<= confirmed_through` are confirmed; frames `> confirmed_through`
* are speculative. There is no per-frame metadata.
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
export class SpeculationLog {
#confirmed_through;
constructor() {
/**
* The most recent frame known to be confirmed. -1 if no frame has been confirmed yet.
* @type {number}
* @private
*/
this.#confirmed_through = -1;
}
/**
* Advance the confirmed boundary. Monotonic: setting an older frame is a no-op.
* @param {number} frame
*/
mark_confirmed(frame) {
assert.isNonNegativeInteger(frame, 'frame');
if (frame > this.#confirmed_through) {
this.#confirmed_through = frame;
}
}
/**
* @param {number} frame
* @returns {boolean}
*/
is_confirmed(frame) {
assert.isInteger(frame, 'frame');
return frame <= this.#confirmed_through;
}
/**
* @param {number} frame
* @returns {boolean}
*/
is_speculative(frame) {
assert.isInteger(frame, 'frame');
return frame > this.#confirmed_through;
}
/**
* @returns {number} the most recent confirmed frame, or -1 if none
*/
confirmed_through() {
return this.#confirmed_through;
}
/**
* Reset the log (e.g. on disconnect).
*/
reset() {
this.#confirmed_through = -1;
}
}