@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
98 lines • 4 kB
TypeScript
/**
* Initial-sync state stream generator.
*
* When a new peer joins, it needs the current state of the world before any
* incremental {@link ActionLog} updates make sense. Snapshotter walks every
* entity in scope, asks each replicated component for its serialized state,
* and writes a flat record stream into a `BinaryBuffer`. The receiver reads
* the stream, creates local entities, attaches components, and registers each
* in the local {@link ReplicationSlotTable} at the matching network_id.
*
* This is a one-shot operation, separate from the per-tick action machinery:
* - Uses the same {@link BinaryClassSerializationAdapter}s as the action log.
* - Does NOT go through the executor — initial sync isn't a reversible mutation.
* - Wire format is minimal; no action_type tags, no prior state.
*
* Wire format:
* ```
* varint: entity_count
* loop entity_count times:
* varint: network_id
* uint8: component_count
* loop component_count times:
* uint8: component_type_id
* uint32: payload_len
* bytes: payload (adapter.serialize)
* ```
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
/**
* Walk every entity in the scope and write a snapshot stream into `buffer`.
*
* @param {{
* buffer: BinaryBuffer,
* world: EntityComponentDataset,
* slot_table: ReplicationSlotTable,
* component_registry: ReplicatedComponentRegistry,
* entity_iter: function(function(number): void): void,
* }} options where `entity_iter(cb)` invokes `cb(entity_id)` for each in-scope entity
*/
export function snapshotter_emit({ buffer, world, slot_table, component_registry, entity_iter }: {
buffer: BinaryBuffer;
world: EntityComponentDataset;
slot_table: ReplicationSlotTable;
component_registry: ReplicatedComponentRegistry;
entity_iter: (arg0: (arg0: number) => void) => void;
}): void;
/**
* Apply a snapshot stream to a (typically empty) world, creating each entity
* and attaching components.
*
* @param {{
* buffer: BinaryBuffer,
* buffer_end: number,
* world: EntityComponentDataset,
* slot_table: ReplicationSlotTable,
* component_registry: ReplicatedComponentRegistry,
* }} options buffer is read starting from its current position; reading stops at `buffer_end`
*/
export function snapshotter_apply({ buffer, buffer_end, world, slot_table, component_registry }: {
buffer: BinaryBuffer;
buffer_end: number;
world: EntityComponentDataset;
slot_table: ReplicationSlotTable;
component_registry: ReplicatedComponentRegistry;
}): void;
/**
* Apply a snapshot stream to existing entities, updating their components in
* place via `adapter.deserialize`. Wire format is identical to {@link snapshotter_emit};
* only the apply semantics differ.
*
* Used by the recovery flow: server emits the current state of a list of
* mutated entities; client applies those bytes to its already-existing local
* counterparts. Entities the receiver doesn't know about are skipped silently
* (their payload bytes are still consumed so the parser stays aligned).
*
* Skipped also: unknown `component_type_id` (forward-compat with newer servers
* that replicate components the receiver doesn't recognise), and components
* the local entity doesn't currently have (the receiver hasn't been told to
* attach this component — recovery doesn't change entity composition, only state).
*
* @param {{
* buffer: BinaryBuffer,
* buffer_end: number,
* world: EntityComponentDataset,
* slot_table: ReplicationSlotTable,
* component_registry: ReplicatedComponentRegistry,
* }} options
*/
export function snapshotter_apply_to_existing({ buffer, buffer_end, world, slot_table, component_registry }: {
buffer: BinaryBuffer;
buffer_end: number;
world: EntityComponentDataset;
slot_table: ReplicationSlotTable;
component_registry: ReplicatedComponentRegistry;
}): void;
//# sourceMappingURL=Snapshotter.d.ts.map