Multiplayer
orblit-net replicates component columns, not objects.
That follows from the core. The store already holds every Transform
contiguously, so a column is the natural unit to send, and sending one is a
memcpy rather than a walk over a graph serialising each node in turn.
What goes on the wire
Section titled “What goes on the wire”Deltas against an acknowledged baseline, rather than 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;}Ownership
Section titled “Ownership”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’s the boring, correct answer to a class of bug that’s very hard to find any other way. Without an ownership rule, two peers writing the same column give you a value that depends on packet arrival order, and it will be right in testing and wrong out in the world.
Interpolation
Section titled “Interpolation”Updates arrive at whatever rate the network manages, and a frame needs a value for now, between two of them.
This is the third place sampling pays for itself. The received values are two moments, and what gets drawn is the moment in between. Nothing in the renderer knows the network exists at all.
Transports
Section titled “Transports”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 bytes to another machine.
Two come with it.
LoopbackLink wires two transports to each other in the same process,
with optional latency. That’s 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 a
real piece of work, and it isn’t the piece that makes Orblit worth using. When
the frame budget says otherwise, Transport is where a datagram transport
goes, and a game needing one that Orblit doesn’t ship can write it in an
afternoon.
What is not here
Section titled “What is not here”There’s 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.
