UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

109 lines 4.28 kB
/** * Sentinel sender id for actions that originated on the local peer (not * received over the wire). Used as the default `sender_id` for * {@link SimActionExecutor#execute} so existing single-peer code keeps * working. Valid peer ids must therefore be in `[0, 254]`. * * @type {number} */ export const SENDER_LOCAL: number; /** * The single legitimate gateway for replicated state mutations. * * On `execute(action, sender_id)`: * 1. Iterate `action.affected_components((entity_id, component_class) => ...)`. * For each, look up the live component on `world`, look up its replication * adapter via the binary registry, and write * `(entity_id, component_type_id, payload_len, payload)` into the current * frame's `ActionLog` buffer. * 2. Call `action.apply(world)`. * 3. Append `(action_type_id, sender_id, action_payload_len, action_payload)` * to the same frame's buffer. `sender_id` is the peer that originated * the action — used by rollback orchestrators for stable-sort tie- * breaking when reconstructing per-tick action order. Defaults to * {@link SENDER_LOCAL} for actions generated by this peer. * * Code outside the executor that wants to mutate replicated state is doing it * wrong: such mutations will not be replicated, will not be reversible, and * will desync clients on rollback. Use a `SimAction`. * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class SimActionExecutor { /** * @param {{ * world: EntityComponentDataset, * action_log: ActionLog, * action_registry: SimActionRegistry, * component_registry: ReplicatedComponentRegistry, * slot_table: ReplicationSlotTable, * changed_entities?: ChangedEntitySet, * }} options */ constructor({ world, action_log, action_registry, component_registry, slot_table, changed_entities }: { world: EntityComponentDataset; action_log: ActionLog; action_registry: SimActionRegistry; component_registry: ReplicatedComponentRegistry; slot_table: ReplicationSlotTable; changed_entities?: ChangedEntitySet; }); /** * @type {EntityComponentDataset} */ world: EntityComponentDataset; /** * @type {ActionLog} */ action_log: ActionLog; /** * @type {SimActionRegistry} */ action_registry: SimActionRegistry; /** * @type {ReplicatedComponentRegistry} */ component_registry: ReplicatedComponentRegistry; /** * Available to actions (via the executor reference passed to apply / affected_components) * for translating network_id ↔ local entity_id. * @type {ReplicationSlotTable} */ slot_table: ReplicationSlotTable; /** * Optional per-tick "which entities mutated this tick?" sink. When set, * each `execute(action)` translates the action's affected entities to * `network_id`s and adds them to this set. The orchestrator typically * compacts the set into a {@link MutationLedger} at end-of-tick and * clears it for the next. * * Null when the executor is configured for receive-only flows that * don't need to record mutation history. * * @type {ChangedEntitySet|null} */ changed_entities: ChangedEntitySet | null; /** * Optional hook fired at the top of {@link execute}, before * prior-bytes capture. Higher-level orchestrators install this * to normalize the world before the executor reads live state * (e.g. {@link NetworkSession} undoes render-time interpolation * on remote-owned components). Should be idempotent and cheap * when no work is needed. * * @type {(() => void) | null} */ before_execute: (() => void) | null; /** * Execute an action: capture prior state of affected components, apply, log. * * @param {SimAction} action * @param {number} [sender_id] peer that originated this action. * Defaults to {@link SENDER_LOCAL} for locally-originated actions. * Must be in `[0, 254]` for remote-originated actions. */ execute(action: SimAction, sender_id?: number): void; #private; } //# sourceMappingURL=SimActionExecutor.d.ts.map