UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

94 lines 3.43 kB
/** * Per-frame ring of action records. * * Each frame's `BinaryBuffer` holds a sequence of action records. One record per * `SimActionExecutor.execute` call: * * ``` * varint: prior_state_count * loop: * varint: entity_id * uint8: component_type_id (assigned by the ReplicatedComponentRegistry) * uint32: prior_payload_len * bytes: prior_payload (adapter.serialize of the component's prior state) * uint8: action_type_id * uint8: sender_id (peer that originated the action; local-only, * STRIPPED by Replicator before send) * uint32: action_payload_len * bytes: action_payload (the action's own serialize output) * ``` * * Self-describing: records can be skipped without consulting the action registry, * which means rewind code can walk records forward to find boundaries, then * iterate backward to apply prior states — no need to instantiate any actions. * * Note that `sender_id` is recorded in-buffer for local rollback orchestrators * (stable-sort tie-breaking by sender on replay) but never crosses the wire — * {@link Replicator#pack_for_peer} strips it and the receiver derives sender * from the inbound packet's peer_id, so a hostile peer cannot impersonate. * * Ring depth is set at construction. When the ring fills, the oldest frame's * buffer is recycled for the new frame. * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class ActionLog { /** * @param {{ frame_capacity: number, initial_buffer_size?: number }} options */ constructor({ frame_capacity, initial_buffer_size }: { frame_capacity: number; initial_buffer_size?: number; }); /** * @readonly * @type {number} */ readonly frame_capacity: number; /** * Open a new frame for writing. Recycles the oldest slot if the ring is full. * * @param {number} frame absolute frame number */ begin_frame(frame: number): void; /** * Close the currently-open frame. */ end_frame(): void; /** * Get the buffer for the currently-open frame for direct writing. * * @returns {BinaryBuffer} */ current_buffer(): BinaryBuffer; /** * Has the given frame number ever been written, and is it still in the ring? * * @param {number} frame * @returns {boolean} */ has_frame(frame: number): boolean; /** * Read-only access to a closed frame's buffer. Throws if the frame is not in the ring. * The buffer's `position` will be set to 0 and its valid byte length is `write_end_for(frame)`. * * **Only valid for frames that have been closed via {@link end_frame}.** While a * frame is open, `__write_ends[slot]` still holds the previous occupant's * length — `buffer_for`/`write_end_for` would return mismatched * buffer-contents-vs-length and any reader would walk garbage. * * @param {number} frame * @returns {BinaryBuffer} */ buffer_for(frame: number): BinaryBuffer; /** * Number of valid bytes written to the given frame's buffer. * @param {number} frame * @returns {number} */ write_end_for(frame: number): number; #private; } import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js"; //# sourceMappingURL=ActionLog.d.ts.map