code wiki / _hdl_build / nx_rollback.nx

nx_rollback.nx source

↩ module page · 43 lines · 2056 B

1// nx_rollback.nx -- N-R4: sovereign ROLLBACK netcode core (P2; the fighting/action-game standard). 2// Predict remote inputs to advance now; when the REAL input arrives and differs, restore the last 3// CONFIRMED snapshot and RE-SIMULATE forward with correct inputs -> the visible state converges to what 4// it would have been with no error, hiding latency. Builds on the deterministic sim (nx_lockstep) so a 5// resim is bit-exact. Pure integer. 100% sovereign. license_tier: ORIGINAL 6import "nx_lockstep.nx" 7 8func rb_copy(dst: *i64, src: *i64, n: i64) -> i64 { var i: i64=0; while i<n { dst[i]=src[i]; i=i+1 } return 0 } 9 10// advance a state buffer over inputs[from..to) using the deterministic step. 11func rb_advance(state: *i64, k: i64, inputs: *i64, from: i64, to: i64) -> i64 { 12 var t: i64 = from 13 while t < to { ls_update(state, k, inputs[t]); t = t + 1 } 14 return 0 15} 16 17// misprediction at tick t? (predicted input != real input) 18func rb_mispredict(predicted: *i64, real: *i64, t: i64) -> i64 { 19 if predicted[t] != real[t] { return 1 } 20 return 0 21} 22 23// the rollback: from a SNAPSHOT taken at confirmed_tick, re-simulate forward to 'to' with REAL inputs. 24// writes the corrected state into out (2*k cells). 25func rb_resim(out: *i64, snapshot: *i64, k: i64, real: *i64, confirmed_tick: i64, to: i64) -> i64 { 26 rb_copy(out, snapshot, 2 * k) 27 rb_advance(out, k, real, confirmed_tick, to) 28 return 0 29} 30 31// ---- latency model (vs delay-based netcode) ---- 32const RBX_BELOW: i64 = 0 33const RBX_PARITY: i64 = 1 34const RBX_EXCEEDS: i64 = 2 35// delay-based netcode waits net_delay frames before applying ANY input -> that many frames of added local 36// input lag. Rollback applies LOCAL input immediately (predicts the remote) -> 0 added local lag. 37func rb_delay_latency(net_delay: i64) -> i64 { return net_delay } 38func rb_rollback_latency() -> i64 { return 0 } 39func rb_latency_verdict(delay_lat: i64, rb_lat: i64) -> i64 { 40 if rb_lat < delay_lat { return RBX_EXCEEDS } 41 if rb_lat == delay_lat { return RBX_PARITY } 42 return RBX_BELOW 43}