Skip to main content

Replication

client.udp is the Replication API over native UDP.

await game.udp.connect(minted)
game.udp.subscribe({"actor_update": lambda n: print(n.uuid, n.chunk, n.payload)})
await game.udp.send_actor_update((0, 0, 0), my_uuid, pose_bytes)
echo = await game.udp.send_actor_update_and_wait((0, 0, 0), my_uuid, pose_bytes)

Connecting mints nothing new. It calls serverWithLeastClients with your app token, waits for the session to be ready, then signs every datagram with that token. The handler names subscribe accepts are actor_update, voxel_update, audio, video, actor_left, text, client_event, server_event, generic_spatial, single_actor_message, channel_message, generic_error, status and any.

Sends on client.udp cover actor updates, voxel updates, audio and video packets (send_video_frame fragments a whole frame), text, client events, single-actor messages and channel publishes. Generic spatial messages and idle heartbeats are on client.udp.connection. Each send returns its sequence number, and each *_and_wait variant resolves with the server's echo or raises on timeout. Sends are bundled into MESSAGE_BUNDLE datagrams; flush_sends() sends the pending bundle now.

A game loop​

On a hot path, use the connection underneath. It sends a frame's entities in one call and reads whole batches of notifications:

conn = game.udp.connection
conn.send_actor_updates(chunks, uuids, poses, stride=88) # numpy: (n, 3) int64, n x 32 octets
async for batch in conn.batches():
actors = batch.types == crowdypy.wire.MessageType.ACTOR_UPDATE_NOTIFICATION
positions = batch.chunks[actors] # a view, not a copy

Each batch is a set of columns: types, app_ids, chunks (n × 3), uuids (n × 32), epoch_ms, sequences, the type-specific extras, and the payloads as offsets into one buffer. They are numpy views of native memory, and nothing is copied until you copy it.

crowdypy.replication.ReplicationConnection is the same connection for code without an event loop: wait(), then poll() from your own loop.

Video and audio​

crowdypy.media fragments video frames onto the wire and reassembles them (fragment_frame, VideoFrameAssembler), using the header format the other SDKs use. send_video_frame and send_audio_packet send them.