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}