Skip to content

Multiplayer

orblit-net replicates component columns, not objects.

That comes straight from the core. The store already keeps every Transform together in one block, so a column is the natural thing to send, and sending one is a memcpy rather than a walk over a graph serialising each node in turn.

Deltas against an acknowledged baseline, not against the last thing sent. Each peer knows which tick the other confirmed and sends the difference from that, so a dropped message costs you one larger snapshot instead of a world that quietly drifts apart.

Which components replicate is declared where they are:

import 'package:orblit_codegen/orblit_codegen.dart';
@OrblitComponent(replicated: true, ownerWritable: true)
class Health {
int value = 100;
}

ownerWritable is the authority rule. A component’s owner may change it and have the change accepted, and anyone else’s write is dropped rather than merged.

It is the dull, correct answer to a bug that is very hard to find any other way. Without an ownership rule, two peers writing the same column give you a value that depends on which packet arrived first, and it will be right in testing and wrong out in the world.

Updates arrive at whatever rate the network manages, and a frame needs a value for now, in between two of them.

This is the third place sampling pays for itself. The values you received are two moments, and what gets drawn is the moment in between. Nothing in the renderer knows the network exists at all.

Transport is a deliberately narrow seam: a stream of framed messages in, a send out, and a close. Everything above it turns a world into bytes, and everything below it gets those bytes to another machine.

Two come with it.

LoopbackLink wires two transports to each other in the same process, with optional latency. That is useful well beyond testing. A single-player build and a listen server both run the real replication path over it, so the networked code path is the only code path, and it can’t rot quietly while nobody is playing multiplayer.

SocketTransport is a WebSocket, with SocketServer on the other end. WebSockets rather than raw UDP for now, and the reason is framing: a snapshot is a message with a length, and WebSocket already delivers whole messages in order. Sequencing, acknowledgement and reassembly on top of datagrams is real work, and it isn’t the work that makes Orblit worth using. If the frame budget says otherwise, Transport is where a datagram transport goes, and a game that needs one Orblit doesn’t ship can write it in an afternoon.

There is no matchmaking, no lobby service, no relay, and no server you can rent. orblit_net is replication and two transports. Everything above that is yours.