flutter3d_net library
Networking over flutter3d_sim: the one transport, the one rollback,
the relay's transports, finding a party, and rollback over the engine's
loop.
One transport and one rollback. Every transport is a PeerWire —
WebSocketTransport through the relay, flutter3d_net_webrtc's data
channel, PeerWire.party over a relay's party room (joinParty,
findParty) — and the rollback is RollbackSession, for two machines or
a party, which EngineRollback runs over an EngineLoop's snapshots and
steps. PeerRoom is two machines meeting, with the hello (WireHello)
that refuses another protocol or another simulation. LoopbackWire and
LoopbackParty stand in for a network in a test, late and lossy as it
asks.
Observing an authoritative simulation, for twins and laboratories: ObserverFeed on the machine that runs it sends each observer (SimulationObserver, over the relay's observer path, observeParty) the tape to replay, telemetry and all, when its profile is bit-exact and the observer runs the same simulation, and the published state (poses, probe readings) otherwise, each filtered by what the observer asked for.
On the 1.0 line. These were flame_multiplayer's before 1.0; the
network core a 1.0 game depends on lives here, and flame_multiplayer
(turns, a ghost's feed, a spectator's tape) is built on it.
Flat Dart. Nothing here needs the Flutter SDK; a relay and a test
run under plain dart test.
Classes
- EngineRollback
-
An
EngineLoopkept in step on two machines or a party of them over a PeerWire: RollbackSession with the loop's snapshots as its state and the loop's steps as its step. - InputStatus
- Where a slot's frame for a step came from: heard from its machine, guessed from the last one heard, or from a machine gone.
- LoopbackPair
-
The two ends LoopbackWire.pair joins: first in slot nought, second
in slot one. Taken apart as
final LoopbackPair(:first, :second) = …. - LoopbackParty
- size machines on one wire in one process, as late and as lossy as a test asks, the same losses for the same seed — the party's LoopbackWire.
- LoopbackWire
- Two PeerWires joined to each other in one process, as late and as lossy as a test asks, and repeatable from its seed.
- ObserverFeed
- The machine that runs the authoritative simulation, sending it to whoever observes: a twin's server to its dashboards, a laboratory's bench to a class, a match to its spectators.
- ObserverFilter
- What one observer wants sent: which probes' readings, by id. Null for every probe.
- ObserverMessages
- The engine's observer messages: under PeerWire.engineKey, so a game's own messages on the same wire never collide with them.
- ObserverMode
- What a SimulationObserver is sent, step by step: the run's tape, to replay into a simulation of its own, or the published state, to draw.
- ObserverRestore
- What SimulationObserver.restore is handed: the feed's state to start the tape from, and the step it was taken after.
- ObserverSnapshot
- Whether a snapshot an observer is sent is the whole state or the change since the last one it was sent.
- PartySeat
- A machine's place in a relay's party: its wire, the slot the relay gave it, the party's code — the one to send a friend — and full, which completes once every player's slot is taken.
- PeerBytes
- Bytes as a PeerWire.listenBytes listener hears them, for the reason PeerMessage gives.
- PeerBytesDelivery
- What PeerWire.deliverBytes is handed, for the reason PeerSend gives.
- PeerDelivery
- What PeerWire.deliver is handed by an adapter, for each message the connection brings, for the reason PeerSend gives.
- PeerMessage
- A message as a PeerWire.listenFrom listener hears it: what arrived, and who sent it.
- PeerRoom
- The room two machines meet in, over the one PeerWire a relay gives them.
- PeerSend
- What PeerWire.send is handed: a message and how it must travel.
- PeerSendBytes
- What PeerWire.sendBytes is handed, for the reason PeerSend gives.
- PeerWire
- Whatever carries messages between machines: a relay's WebSocket, a WebRTC data channel, a game networking library's connection, a party room's fan-out.
-
RollbackSession<
S> - A fixed-step game kept in step on players machines over a PeerWire, each sending its own player's hands: the one rollback, for two machines and for a party alike.
- RollbackStats
- What a RollbackSession has done, read at one moment: how many steps it ran, how many it ran again and what each of those took, and the corrections it could not make.
- RollbackStep
- What RollbackSession.applyAndStep is handed for one step: its number, every slot's frame, where each came from, and whether it is a step run again.
-
SettledStep<
S> - What RollbackSession.onSettled is told of a step as it leaves the window: its number, the state it ended in and the frames it ran on.
- SimulationObserver
- A machine watching an authoritative simulation an ObserverFeed sends.
- SnapshotDivergence
-
Where two runs claiming to be the same actually differ, once
DigestTracehas already said they do. - WebSocketTransport
-
A PeerWire over a plain
WebSocket, throughnet-02's relay —doc/tooling-plan.md's named fallback for whatever a WebRTC data channel could not reach: a platform it has not been wired into yet, or a network whose NAT neither side's ICE candidates got through. - WireHello
- The versions a machine names in its hello, and the rule two hellos are held to.
- WireState
- Whether a PeerWire carries messages.
Functions
-
diffRuns(
{required DigestTrace a, required DigestTrace b, required Map< String, Object?> snapshotAtA(int step), required Map<String, Object?> snapshotAtB(int step)}) → SnapshotDivergence? -
net-04's whole shape:DigestTrace.divergenceFromHexalready finds the step cheaply, from nothing but the eight-digit hex numbers a.f3drunalready carries; this asks for the one thing a digest cannot answer — what, at that step, differed — and only there, rather than at every checkpoint either side ever recorded. -
findParty(
Uri relay, {required String game, int size = 4, String terms = '', SimulationVersion? simulation, void left(int slot)?, Duration timeout = const Duration(seconds: 10)}) → Future< PartySeat> -
Finds a party of
sizeforgameon the relay atrelay— one still filling with strangers who asked for the same, or a new one — and answers with this machine's seat in it. The seat'scodeis the party's, for a friend to join by; itsfullcompletes when the last player arrives, which is when a game should start. -
joinParty(
Uri relay, String code, {int size = 4, bool watching = false, String? owner, String terms = '', SimulationVersion? simulation, void left(int slot)?, Duration timeout = const Duration(seconds: 10)}) → Future< PartySeat> -
Joins the party
codeon the relay atrelay—ws://host:port/— as a player, or withwatchingas a spectator, and answers once the relay has said which slot is this machine's; a party ofsizewhen this machine is the first to ask forcode. -
observeParty(
Uri relay, String code, {required String owner, SimulationVersion? simulation, void left(int slot)?, Duration timeout = const Duration(seconds: 10)}) → Future< PartySeat> -
Joins the party
codeon the relay atrelayas an observer of the authoritative simulation its slot 0 runs: the relay's observer path, let in by theowner's token as a watcher is, whateversimulationit names. What it sends reaches the authority alone, and the authority's messages addressed to its slot reach it alone; aSimulationObserveron the seat's wire does the rest. -
relayRoom(
Uri relay, String code, {String terms = '', SimulationVersion? simulation}) → Uri -
The address of the two-player room
codeon the relay atrelay—ws://host:port/— for WebSocketTransport.connect, asking withterms, this build's protocol and the game'ssimulation, as joinParty does: a machine on another simulation is closed with the relay's reason, which WebSocketTransport.closed answers.
Typedefs
- LoopState = ({Snapshot state, int step})
- A state an EngineRollback keeps of its loop: the step count and every part of the state the loop's snapshots hold.