v0.5.0

Provides ENet-backed board networking. A board can listen for incoming peers and connect to other boards. Replication packets are streamed from the listening side to incoming subscribers. Connecting peers set focus regions, consume entity lifecycle events, and coordinate explicit ownership transfer through offer/intent/award/ack handshakes driven by JS.

Import #

import * as Network from 'Syncromesh/Network';

Connection lifecycle #

listen
Starts listening for incoming board connections on a port.
listen(port: number, options?: { maxConnections?: number }): Promise<boolean>
connect
Connects to a remote board and returns a local connection ID.
connect(host: string, port: number, options?: { clientOnly?: boolean }): Promise<number>
disconnect
Disconnects one connection by ID.
disconnect(connectionId: number): Promise<boolean>
disconnectAll
Disconnects all active network connections for this board.
disconnectAll(): Promise<boolean>
listConnections
Returns current connection state including direction, focus, and auth status.
listConnections(): Promise<Array<{ id: number, host: string, port: number, connected: boolean, incoming: boolean, clientOnly: boolean, focus: AABB | null, authState: 'disabled' | 'pending' | 'accepted' | 'rejected', authRequired: boolean }>>

Authentication handshake #

setAuthConfig
Configures post-connect authentication. When enabled, connections remain pending until accepted.
setAuthConfig(options?: { enabled?: boolean, timeoutMs?: number, allowUnauthenticatedMessages?: boolean }): Promise<{ enabled: boolean, timeoutMs: number, allowUnauthenticatedMessages: boolean }>
getAuthConfig
Returns active authentication policy.
getAuthConfig(): Promise<{ enabled: boolean, timeoutMs: number, allowUnauthenticatedMessages: boolean }>
acceptConnection
Listener-side only: marks an incoming pending connection as accepted and enables privileged traffic.
acceptConnection(connectionId: number): Promise<boolean>
denyConnection
Listener-side only: rejects an incoming pending connection and disconnects it.
denyConnection(connectionId: number, options?: { reason?: number }): Promise<boolean>
getConnectionAuthState
Returns current auth state for one connection ID.
getConnectionAuthState(connectionId: number): Promise<'disabled' | 'pending' | 'accepted' | 'rejected'>

Focus and ownership #

setFocus
Sets the replication focus window for one connection.
setFocus(connectionId: number, focus: AABB): Promise<boolean>
clearFocus
Clears the focus window for one connection.
clearFocus(connectionId: number): Promise<boolean>
setBoardArea
Defines this board's world-space frame. Local simulation coordinates are translated to/from world coordinates using this area origin.
setBoardArea(area: AABB): Promise<boolean>
clearBoardArea
Clears board world-frame translation so local and world coordinates are treated as the same space.
clearBoardArea(): Promise<boolean>
getBoardArea
Returns the configured board-owned area or null if unset.
getBoardArea(): Promise<AABB | null>
localToWorld
Converts a point from board-local coordinates to world coordinates using current board area origin.
localToWorld(position: Point): Promise<Point>
worldToLocal
Converts a world-space point into this board's local coordinate space.
worldToLocal(position: Point): Promise<Point>
ownsPoint
Checks whether server-only code should run for a world-space point.
ownsPoint(position: Point): Promise<boolean>
isEntityOwned
Returns whether an entity is currently owned by this board.
isEntityOwned(entityId: number): Promise<boolean>
isEntityRemoteBound
Returns whether an entity currently has a remote replication binding on this board.
isEntityRemoteBound(entityId: number): Promise<boolean>
offerEntityOwnership
Owner-side call. Broadcasts an ownership offer for one entity to connected peers using the entity UID.
offerEntityOwnership(entityId: number): Promise<boolean>
ackEntityOwnershipOffer
Peer-side call. Acknowledges an offer and promotes the local remote-bound entity to owned if the handshake packet is sent.
ackEntityOwnershipOffer(connectionId: number, remoteEntityId: number, localEntityId: number): Promise<boolean>
setClientOnly
Sets local mode; client-only mode never runs server-only entity code.
setClientOnly(clientOnly: boolean): Promise<boolean>
isClientOnly
Returns whether this board is currently configured as client-only.
isClientOnly(): Promise<boolean>

Message channel #

send
Sends a reliable script message on a connection.
send(connectionId: number, topic: string, payload: string): Promise<boolean>
broadcast
Broadcasts a reliable script message and returns the number of peers that received it.
  • audience: 'incomingClientOnly' targets end-client peers only (client-only boards), excluding sibling server-capable boards.
  • audience: 'incoming' targets all incoming peers.
  • audience: 'all' targets both incoming and outgoing peers.
broadcast(topic: string, payload: string, options?: { audience?: 'all' | 'incoming' | 'incomingClientOnly' }): Promise<number>
consumeMessages
Dequeues incoming script messages.
consumeMessages(options?: { max?: number }): Promise<Array<{ connectionId: number, topic: string, payload: string }>>

Entity events #

consumeEntityLifecycleEvents
Dequeues lifecycle events for local entities that are created, deleted, or ownership-transferred by the replication system.
consumeEntityLifecycleEvents(options?: { max?: number }): Promise<Array<{ type: 'created' | 'deleted' | 'ownershipChanged', localEntityId: number, owned: boolean, scriptType: string }>>
consumeOwnershipTransferOffers
Dequeues ownership offers received from other boards. Prefer ownershipTransferOffered event dispatch for live gameplay code.
consumeOwnershipTransferOffers(options?: { max?: number }): Promise<Array<{ connectionId: number, remoteEntityId: number, uid: number }>>

Event dispatch #

setEventDispatch
Configures engine-driven event dispatch so message and entity lifecycle queues are emitted through Helix/Event only when work exists.
setEventDispatch(options?: { messageEvents?: boolean, entityLifecycleEvents?: boolean, maxMessagesPerTick?: number, maxEntityLifecycleEventsPerTick?: number }): Promise<{ messageEvents: boolean, entityLifecycleEvents: boolean, maxMessagesPerTick: number, maxEntityLifecycleEventsPerTick: number }>
getEventDispatch
Returns current event-dispatch settings.
getEventDispatch(): Promise<{ messageEvents: boolean, entityLifecycleEvents: boolean, maxMessagesPerTick: number, maxEntityLifecycleEventsPerTick: number }>

When enabled, runtime emits:

- networkMessage with { connectionId, topic, payload } - ownershipTransferOffered with { connectionId, remoteEntityId, uid } - entityCreated with { type: 'created', localEntityId, owned, scriptType } - entityDeleted with { type: 'deleted', localEntityId, owned, scriptType } - entityOwnershipChanged with { type: 'ownershipChanged', localEntityId, owned, scriptType }

Use Helix/Event.on(...) to subscribe. Avoid mixing queue polling (consumeMessages / consumeEntityLifecycleEvents) with event dispatch for the same stream.

Auth handshakes are expected to use networkMessage topics such as auth:challenge, auth:response, and auth:result.

Replication cadence #

setReplicationRate
Sets outgoing replication broadcast cadence in Hz and returns the applied rate.
setReplicationRate(hz: number): Promise<number>
getReplicationRate
Returns the current outgoing replication broadcast cadence in Hz.
getReplicationRate(): Promise<number>
setEntityReplicationMask
Controls which fields are included in recurring network delta packets for one entity. Unspecified fields keep their current setting.
setEntityReplicationMask(entityId: number, mask: { position?: boolean, rotation?: boolean, linearVelocity?: boolean, angularVelocity?: boolean, travel?: boolean, identity?: boolean, logic?: boolean, data?: boolean, locomotion?: boolean, waypoint?: boolean }): Promise<object>
getEntityReplicationMask
Returns the active delta replication mask for one entity.
getEntityReplicationMask(entityId: number): Promise<{ position: boolean, rotation: boolean, linearVelocity: boolean, angularVelocity: boolean, travel: boolean, identity: boolean, logic: boolean, data: boolean, locomotion: boolean, waypoint: boolean }>
clearEntityReplicationMask
Restores the default all-fields delta replication mask for one entity.
clearEntityReplicationMask(entityId: number): Promise<boolean>
await Network.setEntityReplicationMask(entityId, {
  position: false,
  rotation: false,
  linearVelocity: false,
  angularVelocity: false,
  identity: true,
  data: true,
});

Notes #

  • Default outgoing replication cadence is 20 Hz.
  • Replication stream direction is listener -> incoming peer.
  • Connecting peers send focus and full-state requests; they do not stream authoritative deltas upstream.
  • When auth is enabled, replication/focus/full-state-request handling is admitted only after acceptance. Pending peers can be disconnected by timeout.
  • Authentication is enforced by the listener for incoming peers; connecting clients do not transition auth state locally.
  • Use broadcast(..., { audience: 'incomingClientOnly' }) for local-only FX/events that should appear on end clients but not sibling server-capable boards.
  • Board area defines coordinate frame translation between local simulation space and world replication space.
  • Entity replication masks affect recurring delta packets. Full-state snapshots remain complete so newly visible replicas and mask changes can rebaseline cleanly.