code wiki / (root) / nx_determinism.nx

nx_determinism.nx source

↩ module page · 70 lines · 2811 B

1// nx_determinism.nx -- rollback SYNC-TEST harness (GGPO "1-frame rollback 2// every frame"). PROVES simulation determinism instead of asserting it: 3// every frame, snapshot -> advance -> rollback to the snapshot -> re- 4// advance with the same input, and the re-simulated state checksum MUST 5// equal both the advanced state AND the no-rollback run. Any divergence 6// = a desync bug (the #1 rollback-netcode failure: state not captured in 7// the snapshot). Integer-only sims are deterministic by construction 8// (no float drift) -- this gate turns that structural property into a 9// gated, verified one. 10// 11// Composes nx_crc32c for the state checksum (CLAUDE.md 15). Sovereign. 12// 13// license_tier: ORIGINAL 14 15import "nx_crc32c.nx" 16 17func det_copy(dst: *i64, src: *i64, nwords: i64) -> i64 { 18 var i: i64 = 0 19 while i < nwords { dst[i] = src[i]; i = i + 1 } 20 return 0 21} 22func det_state_checksum(t: *i64, state: *i64, nwords: i64) -> i64 { 23 return crc32c_table(t, state as *u8, nwords * 8) 24} 25 26// A concrete DETERMINISTIC integer sim step (Q16.16-ish physics over an 27// entity array). Output depends ONLY on (state, input) -> deterministic. 28func det_sim_step(state: *i64, nwords: i64, input: i64) -> i64 { 29 var i: i64 = 0 30 while i < nwords { 31 state[i] = state[i] + input + (state[i] >> 3) + i 32 i = i + 1 33 } 34 return 0 35} 36 37// The GGPO rollback verifier. Returns the number of divergences (0 = 38// provably deterministic across rollbacks). 39func det_rollback_verify(t: *i64, state0: *i64, nwords: i64, inputs: *i64, nframes: i64) -> i64 { 40 let live: *i64 = sys_mmap(nwords * 8 + 16) as *i64 41 let save: *i64 = sys_mmap(nwords * 8 + 16) as *i64 42 let alt: *i64 = sys_mmap(nwords * 8 + 16) as *i64 43 let normal_ck: *i64 = sys_mmap(nframes * 8 + 16) as *i64 44 45 // 1) no-rollback reference run 46 det_copy(live, state0, nwords) 47 var f: i64 = 0 48 while f < nframes { 49 det_sim_step(live, nwords, inputs[f]) 50 normal_ck[f] = det_state_checksum(t, live, nwords) 51 f = f + 1 52 } 53 54 // 2) per-frame save -> advance -> rollback -> re-advance, compare 55 var mism: i64 = 0 56 det_copy(live, state0, nwords) 57 f = 0 58 while f < nframes { 59 det_copy(save, live, nwords) // snapshot 60 det_sim_step(live, nwords, inputs[f]) // authoritative advance 61 det_copy(alt, save, nwords) // rollback 62 det_sim_step(alt, nwords, inputs[f]) // re-advance from snapshot 63 let ck_live: i64 = det_state_checksum(t, live, nwords) 64 let ck_alt: i64 = det_state_checksum(t, alt, nwords) 65 if ck_alt != ck_live { mism = mism + 1 } // rollback diverged 66 if ck_live != normal_ck[f] { mism = mism + 1 } // diverged from reference run 67 f = f + 1 68 } 69 return mism 70}