code wiki / _hdl_build / nx_lagcomp_gate.nx
nx_lagcomp_gate.nx source
↩ module page · 40 lines · 2833 B
1// nx_lagcomp_gate.nx -- proves server-side lag compensation (nx_lagcomp): a correctly-aimed action on what the client
2// SAW connects when the server rewinds to that moment, but MISSES if the server naively checks the target's current
3// (already-moved) position. And a genuinely-wrong aim still misses (it's fair adjudication, not auto-hit).
4import "nx_syscalls.nx"
5import "nx_gate_emit_lib.nx"
6import "nx_lagcomp.nx"
7
8func main() -> i64 {
9 g_puts("nx_lagcomp gate (server rewinds history so a catch/hit connects despite RTT, MEASURED)\n" as *u8)
10 var pass: i64 = 0; var total: i64 = 0
11
12 // a target creature moving +2 / server-tick; 1s history ring (60 ticks). now = tick 50.
13 let hist: *i64 = sys_mmap(64*8) as *i64
14 var t: i64 = 0; while t < 64 { hist[t] = t * 2; t = t + 1 }
15 let now: i64 = 50
16 let radius: i64 = 4
17 let cur_pos: i64 = hist[now] // target's CURRENT server position = 100
18
19 // the acting client: latency 7 ticks + interpolation delay 5 ticks = sees the target 12 ticks in the past
20 let rewind: i64 = 7 + 5
21 let seen_pos: i64 = lc_rewind(hist, now, rewind) // hist[38] = 76 -- what the client aimed at
22 let aim: i64 = seen_pos // a CORRECT throw at the seen position
23
24 let hit_naive: i64 = lc_hit(aim, cur_pos, radius) // server checks current pos -> miss
25 let hit_lagcomp: i64 = lc_hit(aim, lc_rewind(hist, now, rewind), radius) // server rewinds -> connect
26
27 // a genuinely-wrong aim (somewhere the target never was at the seen time) must still miss even with lag comp
28 let bad_hit: i64 = lc_hit(seen_pos + 40, lc_rewind(hist, now, rewind), radius)
29
30 g_puts(" [measure] target now=" as *u8); g_pn(cur_pos); g_puts(" client saw it at=" as *u8); g_pn(seen_pos); g_puts(" (rewind " as *u8); g_pn(rewind); g_puts(" ticks) aim=" as *u8); g_pn(aim); g_puts("\n" as *u8)
31 g_puts(" [measure] naive (check current pos)=" as *u8); g_pn(hit_naive); g_puts(" lag-compensated (rewind)=" as *u8); g_pn(hit_lagcomp); g_puts(" wrong-aim w/ lagcomp=" as *u8); g_pn(bad_hit); g_puts("\n" as *u8)
32
33 pass = pass + g_check("correct aim CONNECTS with lag compensation (rewind to what the client saw)" as *u8, hit_lagcomp == 1); total=total+1
34 pass = pass + g_check("same aim MISSES without lag comp (target already moved) -- the unfair case lag-comp fixes" as *u8, hit_naive == 0); total=total+1
35 pass = pass + g_check("a genuinely-wrong aim still misses (fair adjudication, not auto-hit)" as *u8, bad_hit == 0); total=total+1
36
37 g_puts("---- lagcomp gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
38 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
39 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
40}