Skip to content

Server Replicator


type Iterator<T...> = () -> (T...)

What every set_* method accepts as a filter. nil replicates to every ready player. See the player filtering guide.

type FilterInput =
| Player -- a single player
| { [Player]: boolean } -- a whitelist (true) or blacklist (false)
| (player: Player) -> boolean -- a predicate, re-evaluated every collect
| FilterNode -- a filter group

One node of the reactive filter graph. Sources hold a player set, derived nodes combine their inputs and resolve lazily on the next collect. See the player filtering guide.

type FilterOperand = FilterNode | Player | { [Player]: boolean }
type FilterNode = {
-- sources only
set: (self: FilterNode, filter: Player | { [Player]: boolean }) -> (),
add: (self: FilterNode, player: Player) -> (),
remove: (self: FilterNode, player: Player) -> (),
clear: (self: FilterNode) -> (),
-- each returns a new derived node
filter: (self: FilterNode, ...FilterOperand) -> FilterNode, -- intersection
extend: (self: FilterNode, ...FilterOperand) -> FilterNode, -- union
exclude: (self: FilterNode, ...FilterOperand) -> FilterNode, -- difference
members: (self: FilterNode) -> { [Player]: true },
contains: (self: FilterNode, player: Player) -> boolean,
}

Initializes the server replicator. World can be provided here if it wasn’t provided when creating the replicator.

type Server = {
init: (self: Server, world: jecs.World?) -> ()
}
  • world: The world to use for the replicators. Can also be provided when initing the replicator.

Destroys the server replicator. This will disconnect jecs hooks and connections.

type Server = {
destroy: (self: Server) -> ()
}

Marks an entity to be replicated. Calling it again on a networked entity updates its filter. Calling it on an entity stopped with stop_networked revives it along with the components it had. Same as adding replecs.networked.

Components marked with a set_* method before the entity is networked are kept and start replicating here.

type Server = {
set_networked: (self: Server, entity: Entity, filter: FilterInput?) -> ()
}
  • entity: The entity to replicate.
  • filter: Which players receive the entity. nil means every ready player.

Replicates a component or tag reliably. Additions, changes and removals are sent. Same as adding jecs.pair(replecs.reliable, component).

Calling it again updates the filter. Calling it on a component marked with set_once turns it back into a reliable component.

type Server = {
set_reliable: (self: Server, entity: Entity, component: Component, filter: FilterInput?) -> ()
}
  • entity: The networked entity.
  • component: The component or tag to replicate.
  • filter: Which players receive the component. nil means every player that can see the entity.

Replicates a component unreliably. The current value is sent on every collect_unreliable, whether it changed or not. Additions and removals still go through collect_updates. Same as adding jecs.pair(replecs.unreliable, component).

Tags cannot be replicated unreliably, doing so throws an error.

type Server = {
set_unreliable: (self: Server, entity: Entity, component: Component, filter: FilterInput?) -> ()
}
  • entity: The networked entity.
  • component: The component to replicate.
  • filter: Which players receive the component. nil means every player that can see the entity.

Replicates a component or tag reliably, but only its addition and removal. Value changes are ignored until force_change is called. Same as adding jecs.pair(replecs.once, component).

Calling it on a component marked with set_reliable turns it into a once component.

type Server = {
set_once: (self: Server, entity: Entity, component: Component, filter: FilterInput?) -> ()
}
  • entity: The networked entity.
  • component: The component or tag to replicate.
  • filter: Which players receive the component. nil means every player that can see the entity.

Replicates every pair of a relation on the entity. Targets added and removed later are tracked too. If a target is an entity, it needs to be networked as well. Same as adding jecs.pair(replecs.relation, relation).

type Server = {
set_relation: (self: Server, entity: Entity, relation: Component, filter: FilterInput?) -> ()
}
  • entity: The networked entity.
  • relation: The relation whose pairs to replicate.
  • filter: Which players receive the pairs. nil means every player that can see the entity.

Replicates a single pair reliably, instead of every pair of a relation. The pair value is replicated if the relation or the target is a component. If the target is an entity, it needs to be networked as well.

There is no pair API equivalent, this can only be done with this method.

type Server = {
set_pair: (self: Server, entity: Entity, id: Pair, filter: FilterInput?) -> ()
}
  • entity: The networked entity.
  • id: The full pair id, from jecs.pair(relation, target).
  • filter: Which players receive the pair. nil means every player that can see the entity.

Replicates a single pair unreliably. Like set_unreliable, the value is sent on every collect_unreliable, and the addition and removal go through collect_updates.

The pair must have a value, pair tags throw an error. There is no pair API equivalent.

type Server = {
set_unreliable_pair: (self: Server, entity: Entity, id: Pair, filter: FilterInput?) -> ()
}
  • entity: The networked entity.
  • id: The full pair id, from jecs.pair(relation, target).
  • filter: Which players receive the pair. nil means every player that can see the entity.

Stops replicating an entity. The client deletes the entity on the next collect_updates. The server entity and its components are untouched, and set_networked brings it back with the components it had. Same as removing replecs.networked.

type Server = {
stop_networked: (self: Server, entity: Entity) -> ()
}
  • entity: The entity to stop replicating.

server:stop_reliable(), server:stop_unreliable(), server:stop_once()

Section titled “server:stop_reliable(), server:stop_unreliable(), server:stop_once()”

Stops replicating a component marked with the matching set_* method. The client removes the component on the next collect_updates. Same as removing the matching replecs.* pair.

A component stopped this way does not come back when a stopped entity is revived with set_networked.

type Server = {
stop_reliable: (self: Server, entity: Entity, component: Component) -> (),
stop_unreliable: (self: Server, entity: Entity, component: Component) -> (),
stop_once: (self: Server, entity: Entity, component: Component) -> (),
}
  • entity: The networked entity.
  • component: The component to stop replicating.

server:stop_relation(), server:stop_pair(), server:stop_unreliable_pair()

Section titled “server:stop_relation(), server:stop_pair(), server:stop_unreliable_pair()”

Stops replicating a relation or a single pair marked with the matching set_* method. The client removes the pairs on the next collect_updates.

type Server = {
stop_relation: (self: Server, entity: Entity, relation: Component) -> (),
stop_pair: (self: Server, entity: Entity, id: Pair) -> (),
stop_unreliable_pair: (self: Server, entity: Entity, id: Pair) -> (),
}
  • entity: The networked entity.
  • relation / id: The relation or full pair id to stop replicating.

Marks a component as changed so its current value is sent on the next collect_updates. This is how you replicate a new value for a component marked with set_once.

It only affects components marked with set_reliable or set_once. It does nothing for unreliable components, pairs or relations.

type Server = {
force_change: (self: Server, entity: Entity, component: Component) -> ()
}
  • entity: The networked entity.
  • component: The component to mark as changed.

Returns an iterator that will send batched updates.

type Server = {
collect_updates: (self: Server) -> Iterator<player: Player, buf: buffer, variants: {{any}}>
}
  • player: The player to send the updates to.
  • buf: The buffer containing the updates.
  • variants: The variants table containing non-serialized values.

Returns an iterator that will send the values of unrealible components.

type Server = {
collect_unreliable: (self: Server) -> Iterator<player: Player, buf: buffer, variants: {{any}}>
}
  • player: The player to send the updates to.
  • buf: The buffer containing the updates.
  • variants: The variants table containing non-serialized values.

Gets the full state of the world for the provided player.

type Server = {
get_full: (self: Server, player: Player) -> (buffer, {any})
}
  • player: The player to get the full state of the world for.
  • buf: The buffer containing the full state of the world.
  • variants: The variants table containing non-serialized values.

Encodes a component for sending through the network. This returns the index of the component in the shared components list, a number from 1 to get_shared_count(). Throws an error if the component is not shared.

type Server = {
encode_component: (self: Server, component: Entity) -> number
}
  • component: The component to encode.
  • number: The encoded component.

Decodes a component from a number.

type Server = {
decode_component: (self: Server, encoded: number) -> Component?
}
  • number: The number to decode, This is number from encode_component.
  • component: The decoded component, or nil if the number does not match a shared component.

Creates a source filter bound to this server. Every set_* method and the replecs.networked / replecs.reliable / … components accept it in place of a plain filter.

type Server = {
filter: (self: Server, initial: (Player | { [Player]: boolean })?) -> FilterNode
}
  • initial: The starting member set. A set of false values makes a blacklist.

Creates a filter driven by a predicate over the registered players. The predicate is re-evaluated once per collect.

type Server = {
filter_predicator: (self: Server, predicate: (player: Player) -> boolean) -> FilterNode
}
  • predicate: Returns whether the player is part of the filter.

A filter of every registered player, the base to derive blacklists from.

type Server = {
everyone: (self: Server) -> FilterNode
}

Marks a player as ready to receive updates. Non ready players will not receive updates until this is called.

type Server = {
mark_player_ready: (self: Server, player: Player) -> ()
}
  • player: The player to mark as ready.

Checks if a player has been marked as ready to receive updates.

type Server = {
is_player_ready: (self: Server, player: Player) -> boolean
}
  • player: The player to check.
  • boolean: Whether the player is ready.

Adds an alias for a player. This can be used to use different values like entities in player filters.

type Server = {
add_player_alias: (self: Server, player: Player, alias: any) -> ()
}
  • player: The player to add the alias for.
  • alias: The alias to add.

Removes an alias for a player. This is important to do when a player leaves the server.

type Server = {
remove_player_alias: (self: Server, alias: any) -> ()
}
  • alias: The alias to remove.

Generates a handshake info. This can be used to verify that the server and client are setup correctly.

type Server = {
generate_handshake: (self: Server) -> HandshakeInfo
}
  • handshake: The handshake info. This can be passed to client:verify_handshake()

Verifies a handshake info from client:generate_handshake().

type Server = {
verify_handshake: (self: Server, handshake: HandshakeInfo) -> (success: boolean, err: string?)
}
  • handshake: The handshake info to verify.
  • success: Whether the handshake info is valid.
  • err: The error message if the handshake was not successful.

Returns how many shared components there are. Every number returned by encode_component is between 1 and this value, so you can use it to size buffers or validate a number before calling decode_component.

type Server = {
get_shared_count: (self: Server) -> number
}
  • count: The number of shared components.

Registers a custom id handler. Custom ids can only be used if they are registered.

type Server = {
register_custom_id: (self: Server, custom_id: CustomId) -> ()
}
  • custom_id: The custom id to register.

Gives an entity a global id. The entity is then sent as a single byte, and the client resolves it with client:handle_global(). See the entity remapping guide.

type Server = {
set_global: (self: Server, entity: Entity, global_id: number) -> ()
}
  • entity: The entity to identify.
  • global_id: A number from 0 to 245. Higher values throw an error.

Removes the global id of an entity. It is sent as a normal entity afterwards.

type Server = {
remove_global: (self: Server, entity: Entity) -> ()
}
  • entity: The entity to remove the global id from.

Gives an entity a custom id. Same as adding jecs.pair(replecs.custom, custom). See the entity remapping guide.

An entity can only have one custom id, setting a second one is ignored with a warning. A CustomId must be registered with register_custom_id first.

type Server = {
set_custom: (self: Server, entity: Entity, custom: Component | CustomId) -> ()
}
  • entity: The entity to identify.
  • custom: A component with a replecs.custom_handler, or a CustomId.

Removes the custom id of an entity.

type Server = {
remove_custom: (self: Server, entity: Entity) -> ()
}
  • entity: The entity to remove the custom id from.

Sets the serdes of a component or pair. This is the same as setting the replecs.serdes component. Serdes take part in the handshake, so the client must set a matching one.

type Server = {
set_serdes: <T>(self: Server, id: Component<T>, serdes: Serdes<T>) -> ()
}
  • id: The component or pair to set the serdes to.
  • serdes: The serdes table.

Removes the serdes of a component or pair.

type Server = {
remove_serdes: (self: Server, id: Component) -> ()
}
  • id: The component or pair to remove the serdes from.

Sets the preprocessor of a component or pair. The preprocessor runs before the serdes when writing a value. The handshake checks that the client also has a preprocessor for this component, but not what it does, so make sure it matches.

When set to a pair, the exact pair is used first, then jecs.pair(relation, jecs.Wildcard).

type Server = {
set_preprocessor: <B, A>(self: Server, id: Component<B>, preprocessor: Preprocessor<B, A>) -> ()
}
  • id: The component or pair to set the preprocessor to.
  • preprocessor: The preprocessor table.

Removes the preprocessor of a component or pair.

type Server = {
remove_preprocessor: (self: Server, id: Component) -> ()
}
  • id: The component or pair to remove the preprocessor from.