code wiki / _hdl_build / nx_pets_mp_relay_gate.nx

nx_pets_mp_relay_gate.nx source

↩ module page · 105 lines · 5227 B

1// nx_pets_mp_relay_gate.nx -- proves multiplayer pixelmon player-state transport: 2// the sovereign player-state codec (nx_pets_netstate) carried over the sovereign 3// server-relay (nx_room_relay) = no WebRTC/STUN/TURN/WebSocket. Each player POSTs a 4// packed snapshot; another player reads the roster, fetches that peer's frame, unpacks 5// it -> its decoded position/species. This is the exact transport MP-R1/R2 build on. 6// 1) round-trip: A & B in a room -> A sees B in roster + decodes B's pos/species 7// (B's z is NEGATIVE -> exercises sign-extended i32 decode) 8// 2) room isolation (neg-control): a peer in another room never appears 9// 3) staleness: peers past TTL drop from the roster 10// 4) bad-magic reject (neg-control): ps_unpack on garbage returns 0, no fabricated data 11// 5) anti-tautology: A's decoded state != B's decoded state (real per-peer frames) 12// Built nx_cc_sovereign -> nxasm_x86 (no gcc, no .sh). 13// license_tier: ORIGINAL 14import "nx_syscalls.nx" 15import "nx_gate_emit_lib.nx" 16import "nx_room_relay.nx" 17import "nx_pets_netstate.nx" 18 19func setf(f: *i64, x: i64, y: i64, z: i64, yaw: i64, pitch: i64, sp: i64, caught: i64, act: i64, anim: i64, flags: i64) -> i64 { 20 f[0]=x; f[1]=y; f[2]=z; f[3]=yaw; f[4]=pitch 21 f[5]=sp; f[6]=caught; f[7]=act; f[8]=anim; f[9]=flags 22 return 0 23} 24 25func main() -> i64 { 26 g_puts("nx_pets_mp_relay gate (sovereign multiplayer pixelmon state transport)\n" as *u8) 27 var pass: i64 = 0; var total: i64 = 0 28 29 let N: i64 = 8 30 let SB: i64 = 64 // 28-byte frame fits with room to grow 31 let st: *i64 = sys_mmap((2 + 5*N) * 8) as *i64 32 let arena: *u8 = sys_mmap(N * SB) 33 rr_init(st, N, SB) 34 35 let ROOM_GAME: i64 = 0x7E70 36 let ROOM_OTHER: i64 = 0x9999 37 let PA: i64 = 100 38 let PB: i64 = 101 39 let PC: i64 = 200 40 41 // pack + post player A (peer 100) and player B (peer 101) into ROOM_GAME 42 let fa: *i64 = sys_mmap(10*8) as *i64 43 let fb: *i64 = sys_mmap(10*8) as *i64 44 let pa: *u8 = sys_mmap(SB) 45 let pb: *u8 = sys_mmap(SB) 46 setf(fa, 10, 4, 20, 128, 0-13, 2, 3, 1, 0, 1) // A: z=+20 47 setf(fb, 30, 5, 0-7, 900, 0, 1, 5, 2, 1, 0) // B: z=-7 (negative -> sign test) 48 let la: i64 = ps_pack(pa, fa) 49 let lb: i64 = ps_pack(pb, fb) 50 rr_post(st, arena, ROOM_GAME, PA, 1000, 1, pa, la) 51 rr_post(st, arena, ROOM_GAME, PB, 1000, 1, pb, lb) 52 53 // 1) ROUND-TRIP: from A's view, roster -> [101]; fetch B's frame, unpack, check pos/species 54 let out: *i64 = sys_mmap(N * 8) as *i64 55 let dec: *i64 = sys_mmap(10*8) as *i64 56 var c1: i64 = rr_roster(st, ROOM_GAME, PA, 1000, 8000, out) 57 var r1: i64 = 1 58 if c1 != 1 { r1 = 0 } 59 if out[0] != PB { r1 = 0 } 60 let sB: i64 = rr_live(st, ROOM_GAME, PB, 1000, 8000) 61 if sB < 0 { r1 = 0 } else { 62 let ok: i64 = ps_unpack((arena + sB*SB) as *u8, rr_flen(st, sB), dec) 63 if ok != 1 { r1 = 0 } 64 if dec[0] != 30 { r1 = 0 } // x 65 if dec[2] != (0-7){ r1 = 0 } // z (negative, sign-extended) 66 if dec[5] != 1 { r1 = 0 } // species_held 67 if dec[6] != 5 { r1 = 0 } // caught_count 68 if dec[7] != 2 { r1 = 0 } // action 69 } 70 pass = pass + g_check("round-trip: A decodes B's pos/species over the relay" as *u8, r1); total=total+1 71 72 // 2) ROOM ISOLATION (neg-control): peer 200 in ROOM_OTHER never appears in A's roster 73 let pc: *u8 = sys_mmap(SB) 74 let fc: *i64 = sys_mmap(10*8) as *i64 75 setf(fc, 99, 9, 99, 0, 0, 3, 1, 0, 0, 0) 76 rr_post(st, arena, ROOM_OTHER, PC, 1000, 1, pc, ps_pack(pc, fc)) 77 let c2: i64 = rr_roster(st, ROOM_GAME, PA, 1000, 8000, out) 78 pass = pass + g_check("room isolation: other-room peer absent (still 1)" as *u8, c2 == 1); total=total+1 79 80 // 3) STALENESS: advance now past TTL -> roster empties 81 let c3: i64 = rr_roster(st, ROOM_GAME, PA, 20000, 8000, out) 82 pass = pass + g_check("stale peers (past TTL) drop from roster" as *u8, c3 == 0); total=total+1 83 84 // 4) BAD-MAGIC REJECT (neg-control): garbage frame -> unpack returns 0, no data 85 let bad: *u8 = sys_mmap(SB) 86 var k: i64 = 0; while k < SB { bad[k] = 0xFF as u8; k=k+1 } 87 let rbad: i64 = ps_unpack(bad, 28, dec) 88 pass = pass + g_check("bad-magic frame rejected (unpack=0)" as *u8, rbad == 0); total=total+1 89 90 // 5) ANTI-TAUTOLOGY: A's own decoded state differs from B's (real per-peer frames) 91 rr_post(st, arena, ROOM_GAME, PA, 21000, 2, pa, la) // refresh A so it's live again 92 let sA2: i64 = rr_live(st, ROOM_GAME, PA, 21000, 8000) 93 var r5: i64 = 1 94 let decA: *i64 = sys_mmap(10*8) as *i64 95 if sA2 < 0 { r5 = 0 } else { 96 ps_unpack((arena + sA2*SB) as *u8, rr_flen(st, sA2), decA) 97 if decA[0] != 10 { r5 = 0 } // A.x == 10 98 if decA[0] == dec[0] { r5 = 0 } // A.x (10) != B.x (30) -> not a constant 99 } 100 pass = pass + g_check("anti-tautology: A.x=10 distinct from B.x=30" as *u8, r5); total=total+1 101 102 g_puts("---- pets-mp-relay gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 103 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 104 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 105}