code wiki / _hdl_build / nx_netsync.nx
nx_netsync.nx
buildroot/runtime/_hdl_build/nx_netsync.nx
about
nx_netsync.nx -- the SOVEREIGN MULTIPLAYER NETCODE PART. nx_gamebench gap-queue rank 1
(networking-multiplayer, PARTIAL, blocks Freeciv-class and Veloren-class titles): the existing
nx_lockstep / nx_rollback cores prove the MECHANISM on a synthetic toy stepper only -- nothing
composed netcode with the CERTIFIED GAME PARTS. This part is that composition: deterministic
lockstep sessions whose simulation IS nx_worldsim (the certified faction/economy world), whose
snapshots ARE nx_gamesave files, so every property those parts certified carries onto the wire.
THE INVARIANTS THIS PART EXISTS TO HOLD (each a gate tooth in nx_netsync_gate):
1. LOCKSTEP: only INPUTS cross the wire. Every peer runs the same deterministic sim; a session
advances tick T only when commands from ALL peers for T are present. It STALLS rather than
guesses -- advancing on partial input is the defining desync bug of lockstep netcode.
2. ARRIVAL-ORDER IMMUNE: commands may arrive shuffled, duplicated, or late; duplicates are
idempotent, a CONFLICTING resend (same tick+peer, different command) is REFUSED loudly --
a peer cannot rewrite its committed input (the cheat/corruption door stays shut).
3. DESYNC DETECTABLE: ns_checksum walks the LIVE shared state independently of any save path
(the GX-9 hollow-verifier law), so two peers comparing checksums localize a divergence to
the exact tick it appears.
4. ROLLBACK-READY: whole-session snapshot/copy primitives make the confirmed-state + throwaway
speculative-head pattern (fighting-game rollback) buildable on top without poisoning the
confirmed input table.
5. DURABLE: the whole session arena is one flat i64 block -> gs_save/gs_load; a late joiner
loads a snapshot file and resumes bit-identically (join-in-progress).
Command wire format: one i64 per (tick,peer): 0 = no-op, else from*100000000 + to*1000000 + amt
= a trade order applied through ws_trade (which conserves, clamps, refuses self-dealing -- the
certified properties do the sanitizing; malformed decode fields die in ws_trade's guards).
LIB ONLY -- no main() by ecosystem convention. license_tier: ORIGINAL expect_exit: 0
dependencies 2 imports · 1 importers
imports: nx_syscalls.nxnx_worldsim.nx
imported by: nx_netsync_gate.nx
structs
| none |
consts
| 29 | const NS_MAGIC_100000000: i64 = 100000000 |
| 30 | const NS_MAGIC_1000000: i64 = 1000000 |
| 31 | const NS_MAGIC_40961: i64 = 40961 |
| 39 | const NS_HDR: i64 = 8 |
| 42 | const NS_OK: i64 = 1 |
| 43 | const NS_DUP: i64 = 0 |
| 44 | const NS_E_TICK: i64 = 0-1 |
| 45 | const NS_E_PEER: i64 = 0-2 |
| 46 | const NS_E_CONFLICT: i64 = 0-3 |
functions
| 48 | func ns_npeers(a: *i64) -> i64 { return a[0] } |
| 49 | func ns_self(a: *i64) -> i64 { return a[1] } |
| 50 | func ns_tick(a: *i64) -> i64 { return a[2] } called by 1: main |
| 51 | func ns_maxticks(a: *i64) -> i64 { return a[3] } |
| 52 | func ns_nfac(a: *i64) -> i64 { return a[4] } |
| 53 | func ns_applied(a: *i64) -> i64 { return a[5] } called by 1: main |
| 54 | func ns_moved(a: *i64) -> i64 { return a[6] } called by 1: main |
| 56 | func ns_words(npeers: i64, maxticks: i64, nfac: i64) -> i64 |
| 59 | func ns_bytes(npeers: i64, maxticks: i64, nfac: i64) -> i64 calls 1: ns_words |
| 62 | func ns_o_cmd(a: *i64) -> i64 { return NS_HDR } |
| 63 | func ns_o_have(a: *i64) -> i64 { return NS_HDR + ns_maxticks(a)*ns_npeers(a) } |
| 64 | func ns_o_world(a: *i64) -> i64 { return NS_HDR + 2*ns_maxticks(a)*ns_npeers(a) } |
| 67 | func ns_world(a: *i64) -> *i64 |
| 71 | func ns_init(a: *i64, npeers: i64, self_id: i64, maxticks: i64, nfac: i64, seed: i64) -> i64 |
| 87 | func ns_cmd_at(a: *i64, t: i64, p: i64) -> i64 { return a[ns_o_cmd(a) + t*ns_npeers(a) + p] } |
| 88 | func ns_have_at(a: *i64, t: i64, p: i64) -> i64 { return a[ns_o_have(a) + t*ns_npeers(a) + p] } |
| 92 | func ns_offer(a: *i64, t: i64, p: i64, cmd: i64) -> i64 |
| 109 | func ns_can_advance(a: *i64) -> i64 |
| 124 | func ns_apply_cmd(w: *i64, cmd: i64) -> i64 |
| 134 | func ns_step(a: *i64, rate: i64) -> i64 |
| 161 | func ns_checksum(a: *i64) -> i64 |
| 179 | func ns_shared_eq(a: *i64, b: *i64) -> i64 |
| 197 | func ns_copy(dst: *i64, src: *i64, n: i64) -> i64 called by 1: main |