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}