diff --git a/crates/sapphire-ecr/lib/index.d.ts b/crates/sapphire-ecr/lib/index.d.ts index b20f09e..137a65c 100644 --- a/crates/sapphire-ecr/lib/index.d.ts +++ b/crates/sapphire-ecr/lib/index.d.ts @@ -32,6 +32,92 @@ export interface spawner { spawn_with_handle(...components: T[]): Handle; } +export type raw_data = Map>; + +/** + * A replicator keeps track of all entities with the passed components and their values - + * whenever a component is changed (add, change, remove) and the replicator listens to it, it's also changed within the contained raw data.\ + * The developer can then calculate the difference on the server and send it to the client every time, + * on which the difference is then applied to the registry.\ + * Albeit it's called a replicator, it doesn't replicate the data by itself. + * It allows the developer to use any networking libary to replicate the changes. + * ```ts + * // server + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * export function system() { + * return () => { + * const difference = replicator.calculate_difference() --> buffer + * // There might not be any difference + * if (!difference) return + * data_replication_event.send_to_all(difference) + * } + * } + * ``` + * ```ts + * // client + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * export function system() { + * return () => { + * for (const [_, difference] = data_replication_event.poll()) { + * replicator.apply_difference(difference) + * } + * } + * } + * ``` + */ +export interface replicator { + /** + * Gets the full data representing the entire registry. + * Useful for initial replication to every player. + * ```ts + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * Players.PlayerAdded.Connect((player) => { + * data_replication_event.send_to(player, replicator.get_full_data()) + * }) + * ``` + * @returns raw_data + */ + get_full_data(): raw_data; + /** + * Calculates the difference between last sent data and currently stored data. + * ```ts + * // server + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * export function system() { + * return () => { + * const difference = replicator.calculate_difference() --> buffer + * // There might not be any difference + * if (!difference) return + * data_replication_event.send_to_all(difference) + * } + * } + * ``` + * @returns raw_data? + */ + calculate_difference(): raw_data | undefined; + /** + * Applies the difference to the current data. + * ```ts + * // client + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * export function system() { + * return () => { + * for (const [_, difference] = data_replication_event.poll()) { + * replicator.apply_difference(difference) + * } + * } + * } + * ``` + * @param difference raw_data + */ + apply_difference(difference: raw_data): void; +} + declare interface WorldDeclaration { readonly identifier: "sapphire-ecr"; readonly methods: Map void>; @@ -42,9 +128,64 @@ declare interface WorldDeclaration { readonly render_stepped_systems: system[]; extension(): void; + /** + * Creates a spawner. + * ```ts + * const spawner = sapphire_ecr.create_spawner(components.part, components.velocity, components.part) + * for (let i = 0; i < 1000; i++) { + * spawner.spawn(part_template.Clone(), Vector3.zero, Vector3.zero) + * } + * ``` + * @param components T[] + * @returns spawner + */ create_spawner(...components: T[]): spawner; + /** + * Creates an entity and returns its id. + * @returns Entity + */ spawn_entity(): Entity; + /** + * Creates an entity and returns a handle to it. + * @returns Handle + */ spawn_entity_with_handle(): Handle; + /** + * Creates a `replicator`. + * A replicator keeps track of all entities with the passed components and their values - + * whenever a component is changed (add, change, remove) and the replicator listens to it, it's also changed within the contained raw data.\ + * The developer can then calculate the difference on the server and send it to the client every time, + * on which the difference is then applied to the registry.\ + * Albeit it's called a replicator, it doesn't replicate the data by itself. + * It allows the developer to use any networking libary to replicate the changes. + * ```ts + * // server + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * export function system() { + * return () => { + * const difference = replicator.calculate_difference() --> buffer + * // There might not be any difference + * if (!difference) return + * data_replication_event.send_to_all(difference) + * } + * } + * ``` + * ```ts + * // client + * const replicator = sapphire_ecr.create_replicator(component_a, component_b, ...) + * + * export function system() { + * return () => { + * for (const [_, difference] = data_replication_event.poll()) { + * replicator.apply_difference(difference) + * } + * } + * } + * ``` + * @returns replicator + */ + create_replicator(): replicator; } /** @readonly */ diff --git a/crates/sapphire-ecr/lib/init.luau b/crates/sapphire-ecr/lib/init.luau index 3b7c0fa..d60ab39 100644 --- a/crates/sapphire-ecr/lib/init.luau +++ b/crates/sapphire-ecr/lib/init.luau @@ -95,7 +95,7 @@ end --- ```luau --- local spawner = sapphire_ecr.create_spawner(components.part, components.velocity, components.position) --- for _ = 1, 1000 do ---- spawner.spawn(part_template:Clone(), Vector3.new(0, 0, 0), Vector3.new(0, 0, 0)) +--- spawner.spawn(part_template:Clone(), Vector3.zero, Vector3.zero) --- end --- ``` --- @param ... T... -- Components to use. @@ -104,7 +104,7 @@ function SapphireEcr.create_spawner(...: T...): spawner return create_spawner(...) end ---- Creates an entity and returns it's id. +--- Creates an entity and returns its id. --- @return ecr.entity function SapphireEcr.spawn_entity(): ecr.entity return SapphireEcr.registry:create() @@ -148,7 +148,7 @@ export type raw_data = { --- --- function singleton.system() --- return function() ---- for _, difference in data_replication_event.poll() +--- for _, difference in data_replication_event.poll() do --- replicator.apply_difference(difference) --- end --- end @@ -227,7 +227,7 @@ export type replicator = { --- --- function singleton.system() --- return function() ---- for _, difference in data_replication_event.poll() +--- for _, difference in data_replication_event.poll() do --- replicator.apply_difference(difference) --- end --- end