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}