code wiki / _hdl_build / nx_wasm_shmup_gate.nx
nx_wasm_shmup_gate.nx source
↩ module page · 97 lines · 6557 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_wasm_shmup_gate.nx -- NATIVE gate for the browser-playable shmup core (nx_wasm_shmup). Runs the SAME
4// base-relative code the wasm runs, with base = a real mmap, to verify the game + render BEFORE lowering to
5// wasm (the verify-by-eye loop that replaces a browser we can't click here).
6// T1 KILL: aim + shoot advances a bullet that destroys an enemy (score rises). PNG (mid-game frame).
7// T2 RENDER REAL: the rendered frame has a green ship + a red enemy + the bullet.
8// T3 GAME-OVER + RESTART: a wave reaching the ship line ends the game; shoot restarts it.
9// T4 NEVER-BRICK (#26): deterministic, bounded, no float, base-relative (no sys_mmap in the core).
10// expect_exit: 0 license_tier: ORIGINAL
11import "nx_wasm_shmup.nx"
12import "nx_png.nx"
13import "nx_syscalls.nx"
14import "nx_gate_verdict.nx"
15
16func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
17" as *u8); return ok }
18
19func main() -> i64 {
20 gw("=== nx_wasm_shmup_gate: browser-playable shmup core, verified NATIVE before wasm ===\n" as *u8)
21 var pass: i64 = 0; var total: i64 = 0
22 let base: i64 = sys_mmap(2*1024*1024) as i64
23 let st: *i64 = (base + O_ST) as *i64
24 let ea: *i64 = (base + O_EA) as *i64
25
26 // ---- T1: aim + shoot + advance -> an enemy is destroyed ----
27 init_impl(base)
28 var m: i64=0; while m < 22 { tick_impl(base, 1); m=m+1 } // move ship left to align with enemy 0 (x=18)
29 tick_impl(base, 4) // fire
30 var f: i64=0; while f < 40 { if st[4] > 0 { f=40 } else { tick_impl(base, 0); f=f+1 } } // advance the bullet
31 var t1ok: i64=1; if st[4] < 10 {t1ok=0} if ea[0] != 0 {t1ok=0}
32 total=total+1; if t1ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
33 gw("T1 kill: aim+shoot destroyed an enemy, score=" as *u8); gn(st[4]); gw(", enemy0 alive=" as *u8); gn(ea[0]); gw("\n" as *u8)
34
35 // ---- render a fresh mid-game frame (ship + bullet in flight + a wave) ----
36 init_impl(base)
37 tick_impl(base, 4) // fire
38 var a: i64=0; while a < 5 { tick_impl(base, 0); a=a+1 } // bullet mid-flight
39 render_impl(base)
40 let fb: *i64 = (base + O_FB) as *i64
41 write_png(fb, W, H, "knowledge/nx_wasm_shmup_native.png" as *u8)
42 gw(" (live evidence: PNG knowledge/nx_wasm_shmup_native.png -- ship + bullet + enemy wave + HUD score)\n" as *u8)
43
44 // ---- T2/T5/T6: render real -- THE SHIP AND THE ENEMY ARE ACTUALLY IN THE PICTURE ----
45 // ★THE OLD TOOTH WAS HALF VACUOUS, AND COMPOUND SO IT COULD NOT SAY WHICH HALF. It asked for
46 // "ship greener than red" and "enemy redder than green" in ONE boolean. The sky is rgb(8,10,24),
47 // whose g=10 EXCEEDS r=8 -- so the ship conjunct passed on EMPTY SKY and would have gone on
48 // passing with the ship draw deleted. (The enemy conjunct was genuine: sky is not reddish.)
49 // Found 2026-08-14 by nx_vacuity_census. Both are now DIFFERENCES against the background, which
50 // names no colour and so cannot rot when the palette moves, and each is its own counted tooth so
51 // a failure names its conjunct instead of leaving the reader to guess.
52 let ship: i64 = fb[SY*W + (W/2)] // ship center
53 let enemy: i64 = fb[st[6]*W + 18] // enemy 0 at (18, ey)
54 let sky1: i64 = fb[(H/2)*W + 2]
55 let sky2: i64 = fb[(H/2)*W + 5]
56 total=total+1; if ship != sky1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
57 gw("T2 render real: the SHIP is in frame -- its cell differs from the sky (ship=" as *u8); gn(ship); gw(" sky=" as *u8); gn(sky1); gw(")\n" as *u8)
58
59 total=total+1; if enemy != sky1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
60 gw("T5 render real: the ENEMY is in frame -- its cell differs from the sky (enemy=" as *u8); gn(enemy); gw(" sky=" as *u8); gn(sky1); gw(")\n" as *u8)
61
62 // neg-control: the two background samples must AGREE, or T2 and T5 could be passing on ordinary
63 // background variation rather than on the ship and the enemy. A star landing on one of these
64 // sample points makes this FAIL LOUDLY rather than quietly weakening the two teeth above.
65 total=total+1; if sky1 == sky2 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
66 gw("T6 neg-control-background-uniform: two sky samples agree (" as *u8); gn(sky1); gw(" vs " as *u8); gn(sky2); gw(")\n" as *u8)
67
68 // ---- T3: game-over when a wave reaches the ship line, restart on shoot ----
69 init_impl(base)
70 var g: i64=0; while g < 2000 { if st[7]==1 { g=2000 } else { tick_impl(base, 0); g=g+1 } }
71 let over: i64 = st[7]
72 tick_impl(base, 4) // shoot -> restart
73 var t3ok: i64=1; if over != 1 {t3ok=0} if st[7] != 0 {t3ok=0}
74 total=total+1; if t3ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
75 gw("T3 game-over+restart: a wave reached the ship line (over=" as *u8); gn(over); gw("), shoot restarted (gameover now=" as *u8); gn(st[7]); gw(")\n" as *u8)
76
77 // ---- T4: never-brick / determinism ----
78 init_impl(base)
79 m=0; while m < 22 { tick_impl(base, 1); m=m+1 } tick_impl(base, 4)
80 f=0; while f < 40 { if st[4] > 0 { f=40 } else { tick_impl(base, 0); f=f+1 } }
81 let score2: i64 = st[4]
82 total=total+1; if score2 >= 10 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
83 gw("T4 never-brick (#26): deterministic re-run (score=" as *u8); gn(score2); gw("), base-relative, no float, no sys_mmap in the core\n" as *u8)
84
85 gw("\n=== nx_wasm_shmup_gate " as *u8); gn(pass); gw("/" as *u8); gn(total)
86 // D001 ANCHOR: the rich line above stays as this gate's public signature; the canonical verdict
87 // goes LAST because the estate's judge anchors by POSITION, taking only the final line.
88 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
89 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
90 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
91 let ctr__dry: *i64 = gv_ctr()
92 ctr__dry[0] = pass
93 ctr__dry[1] = total
94 let rc__dry: i64 = gv_verdict("WASM-SHMUP-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
95 sys_exit(rc__dry)
96 return rc__dry
97}