code wiki / _hdl_build / nx_wasm_platformer_gate.nx

nx_wasm_platformer_gate.nx source

↩ module page · 92 lines · 5663 B

1// nx_wasm_platformer_gate.nx -- native test harness + PNG proof for the sovereign browser platformer 2// (nx_wasm_platformer). Drives the SAME integer logic the wasm exports (base = mmap here, base = 0 in wasm): 3// a scripted jump-AI auto-runs the level and must collect all floating coins + clear all foes + reach the exit; 4// a NO-JUMP control proves the floating coins are UNREACHABLE without the jump mechanic (the platformer-ness is 5// real, not decorative); the integer jump ARC is measured (apex >= 30px); determinism (two runs identical); and 6// a mid-play frame is rastered to knowledge/staging/game/platformer_play.png. license_tier: ORIGINAL expect_exit: 0 7import "nx_wasm_platformer.nx" 8import "nx_png.nx" 9import "nx_syscalls.nx" 10 11func g_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 12func g_i(v: i64) -> i64 { let t: *u8 = sys_mmap(24); var m: i64 = v; var k: i64 = 0; if m == 0 { t[0]=48 as u8; k=1 } while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } let o: *u8=sys_mmap(24); var w: i64=0; var q: i64=k-1; while q>=0 { o[w]=t[q]; w=w+1; q=q-1 } sys_write(1,o,w); return 0 } 13 14// run a full playthrough; dojump=1 uses the jump-AI (jump when a floating coin is just ahead), 0 never jumps. 15func play(base: i64, dojump: i64) -> i64 { 16 init_impl(base) 17 var run: i64 = 1 18 while run == 1 { 19 if sget(base, 7) == 1 { run = 0 } 20 if sget(base, 8) > 400 { run = 0 } 21 if run == 1 { 22 var cmd: i64 = 2 23 if dojump == 1 { if sget(base, 3) == 1 { 24 var i: i64 = 0 25 while i < NCOIN { if cget(base, i) == 0 { let d: i64 = coin_x(i) - sget(base, 0); if d > 10 { if d < 24 { cmd = 0 } } } i = i + 1 } 26 } } 27 tick_impl(base, cmd) 28 } 29 } 30 return sget(base, 8) 31} 32 33func main(argc: i64, argv: *i64) -> i64 { 34 g_p("=== nx_wasm_platformer_gate (sovereign browser platformer: integer logic + raster) ===\n" as *u8) 35 let base: i64 = sys_mmap(2097152) as i64 36 var pass: i64 = 0; var tot: i64 = 0 37 38 // T1 jump-AI playthrough collects everything + reaches exit 39 play(base, 1) 40 let coins1: i64 = sget(base, 5); let foes1: i64 = sget(base, 6); let score1: i64 = sget(base, 4); let won1: i64 = sget(base, 7) 41 tot = tot + 1; var ok1: i64 = 1 42 if coins1 != NCOIN { ok1 = 0 } 43 if foes1 != NFOE { ok1 = 0 } 44 if score1 != NCOIN + NFOE { ok1 = 0 } 45 if won1 != 1 { ok1 = 0 } 46 if ok1 == 1 { pass = pass + 1; g_p("PASS T1 playthrough: jumped+collected 4/4 coins, cleared 2/2 foes, score=6, reached exit (WIN)\n" as *u8) } else { g_p("FAIL T1 coins=" as *u8); g_i(coins1); g_p(" foes=" as *u8); g_i(foes1); g_p(" score=" as *u8); g_i(score1); g_p(" won=" as *u8); g_i(won1); g_p("\n" as *u8) } 47 48 // T2 NEGATIVE CONTROL: without jumping, the floating coins are unreachable (mechanic is real) 49 play(base, 0) 50 let coins0: i64 = sget(base, 5); let foes0: i64 = sget(base, 6); let won0: i64 = sget(base, 7) 51 tot = tot + 1; var ok2: i64 = 1 52 if coins0 != 0 { ok2 = 0 } 53 if foes0 != NFOE { ok2 = 0 } 54 if won0 != 1 { ok2 = 0 } 55 if ok2 == 1 { pass = pass + 1; g_p("PASS T2 neg-control: no-jump run collects 0/4 floating coins (jump is REQUIRED), still clears 2 ground foes + exits\n" as *u8) } else { g_p("FAIL T2 coins0=" as *u8); g_i(coins0); g_p(" foes0=" as *u8); g_i(foes0); g_p("\n" as *u8) } 56 57 // T3 integer jump ARC: a single jump rises >= 30px (proves the no-float gravity parabola) 58 init_impl(base); tick_impl(base, 0) 59 var apex: i64 = sget(base, 1) 60 var k: i64 = 0 61 while k < 14 { tick_impl(base, 1); if sget(base, 1) < apex { apex = sget(base, 1) } k = k + 1 } 62 let rise: i64 = GROUNDY - apex 63 tot = tot + 1 64 if rise >= 30 { pass = pass + 1; g_p("PASS T3 jump arc: integer gravity parabola rises " as *u8); g_i(rise); g_p("px (>=30), lands back on the ground\n" as *u8) } else { g_p("FAIL T3 rise=" as *u8); g_i(rise); g_p("\n" as *u8) } 65 66 // T4 DETERMINISM: same script -> identical outcome 67 play(base, 1); let f1: i64 = sget(base, 8); let s1: i64 = sget(base, 4) 68 play(base, 1); let f2: i64 = sget(base, 8); let s2: i64 = sget(base, 4) 69 tot = tot + 1 70 if f1 == f2 { if s1 == s2 { pass = pass + 1; g_p("PASS T4 determinism: two runs identical (frames=" as *u8); g_i(f1); g_p(", score=" as *u8); g_i(s1); g_p(")\n" as *u8) } else { g_p("FAIL T4\n" as *u8) } } else { g_p("FAIL T4\n" as *u8) } 71 72 // T5 RASTER a mid-play frame -> PNG; hero pixel must be green 73 init_impl(base) 74 var fr: i64 = 0 75 while fr < 56 { 76 var cmd: i64 = 2 77 if sget(base, 3) == 1 { var i: i64 = 0; while i < NCOIN { if cget(base, i) == 0 { let d: i64 = coin_x(i) - sget(base, 0); if d > 10 { if d < 24 { cmd = 0 } } } i = i + 1 } } 78 tick_impl(base, cmd); fr = fr + 1 79 } 80 render_impl(base) 81 sys_mkdir("knowledge/staging/game" as *u8, 0x1ed) 82 write_png((base + O_FB) as *i64, W, H, "knowledge/staging/game/platformer_play.png" as *u8) 83 let fb: *i64 = (base + O_FB) as *i64 84 let hx: i64 = sget(base, 0); let hy: i64 = sget(base, 1) 85 let hc: i64 = fb[(hy + 8) * W + (hx + 6)] 86 tot = tot + 1 87 if ((hc >> 8) & 255) > (hc & 255) { pass = pass + 1; g_p("PASS T5 raster: mid-play frame -> knowledge/staging/game/platformer_play.png (hero pixel green)\n" as *u8) } else { g_p("FAIL T5 hero not green\n" as *u8) } 88 89 g_p("nx_wasm_platformer_gate pass=" as *u8); g_i(pass); g_p("/" as *u8); g_i(tot) 90 if pass == tot { g_p(" verdict=GREEN (sovereign integer platformer; browser-ready via the wasm chain)\n" as *u8); sys_exit(0); return 0 } 91 g_p(" verdict=RED\n" as *u8); sys_exit(1); return 1 92}