code wiki / _hdl_build / nx_wasm_mineworld_tick_gate.nx

nx_wasm_mineworld_tick_gate.nx source

↩ module page · 224 lines · 9969 B

1// nx_wasm_mineworld_tick_gate.nx -- gate for the SOVEREIGN TICK (operator law: NO JS game logic -- the wasm 2// owns camera/physics/trig/aim). T0 integer-trig sanity. T1 walk+mouse-look move the camera (turned heading 3// moves BOTH axes). T2 gravity settles to the surface; jump rises then lands back exactly. T3 a 3-high wall 4// BLOCKS walking (step-up rule <=1.3). T4 aim-ray dig/put edit the world from camera state alone. T5 the whole 5// sim is DETERMINISTIC: an identical input script on two fresh worlds renders byte-identical frames. T6 the 6// per-voxel texture hash varies. PNG knowledge/nx_mineworld_tick.png = post-walk frame (fog + textured blocks). 7// license_tier: ORIGINAL expect_exit: 0 8import "nx_syscalls.nx" 9import "nx_f32_hw.nx" 10import "nx_png.nx" 11import "nx_wasm_mineworld.nx" 12 13func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 14func pn(v: i64) -> i64 { 15 let b: *u8 = sys_mmap(32) as *u8 16 var x: i64 = v 17 var neg: i64 = 0 18 if x < 0 { neg = 1; x = 0 - x } 19 var i: i64 = 31 20 if x == 0 { b[i] = 48 as u8; i = i - 1 } 21 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 } 22 if neg == 1 { b[i] = 45 as u8; i = i - 1 } 23 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i) 24 return 0 25} 26func fbsum(base: i64) -> i64 { 27 let fb: *i64 = (base + fb_off()) as *i64 28 var s: i64 = 0 29 var i: i64 = 0 30 while i < ww() * hh() { s = s * 31 + fb[i]; i = i + 1 } 31 return s 32} 33func iabs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 34// is the camera's HEAD cell still below roof_gy? (the ceiling-clamp assert) 35func c_a_head_below(base: i64, roof_gy: i64) -> i64 { 36 let c: *i64 = cam_ptr(base) 37 let hgy: i64 = mw_fd256(c[1] + 60) 38 if hgy < roof_gy { return 1 } 39 return 0 40} 41// a fixed input script: walk, turn, walk, jump, walk -- exercised identically on two fresh worlds for T5 42func script(base: i64) -> i64 { 43 var i: i64 = 0 44 while i < 20 { tick_at(base, 1, 0, 0); i = i + 1 } 45 tick_at(base, 0, 180, 0 - 40) 46 i = 0 47 while i < 15 { tick_at(base, 1 + 8, 0, 0); i = i + 1 } 48 tick_at(base, 16, 0, 0) 49 i = 0 50 while i < 25 { tick_at(base, 1, 5, 0); i = i + 1 } 51 return 0 52} 53 54func main() -> i64 { 55 var fails: i64 = 0 56 57 // ---- T0 integer trig ---- 58 var t0: i64 = 1 59 if mw_sin4096(0) != 0 { t0 = 0 } 60 if iabs(mw_sin4096(PI2_4096) - 4096) > 25 { t0 = 0 } 61 if iabs(mw_sin4096(PI4096)) > 25 { t0 = 0 } 62 if iabs(mw_sin4096(0 - PI2_4096) + 4096) > 25 { t0 = 0 } 63 if iabs(mw_cos4096(0) - 4096) > 25 { t0 = 0 } 64 if t0 == 1 { hw("T0 PASS integer trig (sin 0/90/180/-90, cos 0 within 0.6%)\n" as *u8) } 65 else { hw("T0 FAIL trig\n" as *u8); fails = fails + 1 } 66 67 // ---- T1 walk + look (base A) ---- 68 let bA: i64 = sys_mmap(mem_bytes()) as i64 69 start_at(bA) 70 let cA: *i64 = cam_ptr(bA) 71 let z0: i64 = cA[2] 72 var i: i64 = 0 73 while i < 30 { tick_at(bA, 17, 0, 0); i = i + 1 } // W+Space: voxel physics has NO auto-step -> hop the bumps 74 let zgain: i64 = cA[2] - z0 75 tick_at(bA, 0, 245, 0) // yaw += ~0.78 rad 76 let x1: i64 = cA[0] 77 let z1: i64 = cA[2] 78 i = 0 79 while i < 30 { tick_at(bA, 17, 0, 0); i = i + 1 } 80 var t1: i64 = 1 81 if zgain < 400 { hw("T1 sub: zgain=" as *u8); pn(zgain); hw("\n" as *u8); t1 = 0 } // trees are solid: the lane may legitimately end at a trunk 82 if cA[0] - x1 < 500 { t1 = 0 } 83 if cA[2] - z1 < 500 { t1 = 0 } 84 if t1 == 1 { hw("T1 PASS walk straight then turned heading moves both axes (in-wasm trig)\n" as *u8) } 85 else { hw("T1 FAIL walk/look\n" as *u8); fails = fails + 1 } 86 87 // ---- T2 gravity + jump (re-anchor on base A wherever it walked to) ---- 88 // GROUND TRUTH is voxel-local, not the column top: the old surface_y assert put you ON TREETOPS (that 89 // WAS the physics bug). Correct rest = feet exactly on a cell boundary, phys-solid directly below, air 90 // at the feet cell (standing under a canopy is legal now). 91 i = 0 92 while i < 30 { tick_at(bA, 0, 0, 0); i = i + 1 } 93 let gy0: i64 = cA[1] 94 let tgx: i64 = mw_fd256(cA[0]) 95 let tgz: i64 = mw_fd256(cA[2]) 96 let tfy: i64 = mw_fd256(gy0 - 410) 97 var t2: i64 = 1 98 if (gy0 - 410) % 256 != 0 { t2 = 0 } 99 if phys_solid(bA, tgx, tfy - 1, tgz) == 0 { t2 = 0 } 100 if phys_solid(bA, tgx, tfy, tgz) == 1 { t2 = 0 } 101 if cA[7] != 1 { t2 = 0 } 102 tick_at(bA, 16, 0, 0) 103 tick_at(bA, 0, 0, 0) 104 if cA[1] <= gy0 { t2 = 0 } 105 i = 0 106 while i < 80 { tick_at(bA, 0, 0, 0); i = i + 1 } 107 if cA[1] != gy0 { t2 = 0 } 108 if cA[7] != 1 { t2 = 0 } 109 if t2 == 1 { hw("T2 PASS gravity settles on the surface; jump rises then lands back exactly\n" as *u8) } 110 else { hw("T2 FAIL gravity/jump\n" as *u8); fails = fails + 1 } 111 112 // ---- T2b VOXEL PHYSICS: ceiling stops the head; water is swimmable not walkable ---- 113 var t2b: i64 = 1 114 // ceiling: build a roof 3 above the ground under the player, jump -> head must stop below it 115 let rgx: i64 = mw_fd256(cA[0]) 116 let rgz: i64 = mw_fd256(cA[2]) 117 let rg: i64 = floor_y(bA, rgx, rgz, YMAX - 1) 118 mw_eset(bA, rgx, rg + 2, rgz, 1) 119 tick_at(bA, 16, 0, 0) 120 var j2: i64 = 0 121 while j2 < 10 { tick_at(bA, 0, 0, 0); j2 = j2 + 1 } 122 // eye must stay below the roof cell bottom the whole arc's end state (head clamp held) 123 if c_a_head_below(bA, rg + 2) == 0 { t2b = 0 } 124 mw_eset(bA, rgx, rg + 2, rgz, 2) // remove the roof (dug) 125 // water: teleport the column state -- find an ocean column near origin scanning gz 126 var wgx: i64 = 0 - 999 127 var wgz: i64 = 0 128 var sz2: i64 = 0 - 60 129 while sz2 < 60 { 130 var sx2: i64 = 0 - 60 131 while sx2 < 60 { 132 if wgx == 0 - 999 { if terrain_h0(sx2, sz2) <= 4 { wgx = sx2; wgz = sz2 } } 133 sx2 = sx2 + 1 134 } 135 sz2 = sz2 + 1 136 } 137 if wgx == 0 - 999 { hw("T2b sub: no ocean column found nearby\n" as *u8); t2b = 0 } 138 else { 139 let cB2: *i64 = cam_ptr(bA) 140 cB2[0] = wgx * 256 + 128 141 cB2[2] = wgz * 256 + 128 142 cB2[1] = 10 * 256 // drop from above sea level 143 cB2[5] = 0 144 var j3: i64 = 0 145 while j3 < 60 { tick_at(bA, 0, 0, 0); j3 = j3 + 1 } 146 // feet must be BELOW the water surface (submerged -- the old physics stood ON the sea at WWATER+1) 147 let feetw: i64 = cB2[1] - 410 148 if feetw >= (WWATER + 1) * 256 { t2b = 0 } 149 // Space swims UP 150 let ybefore: i64 = cB2[1] 151 var j4: i64 = 0 152 while j4 < 8 { tick_at(bA, 16, 0, 0); j4 = j4 + 1 } 153 if cB2[1] <= ybefore { t2b = 0 } 154 } 155 if t2b == 1 { hw("T2b PASS voxel physics: ceiling stops the head; water submerges + Space swims up\n" as *u8) } 156 else { hw("T2b FAIL ceiling/water physics\n" as *u8); fails = fails + 1 } 157 158 // ---- T3 wall blocks walking (fresh base B) ---- 159 let bB: i64 = sys_mmap(mem_bytes()) as i64 160 start_at(bB) 161 let cB: *i64 = cam_ptr(bB) 162 let hh31: i64 = surface_y(bB, 30, 31) 163 mw_eset(bB, 30, hh31, 31, 1) 164 mw_eset(bB, 30, hh31 + 1, 31, 1) 165 mw_eset(bB, 30, hh31 + 2, 31, 1) 166 i = 0 167 while i < 20 { tick_at(bB, 1, 0, 0); i = i + 1 } 168 if mw_fd256(cB[2]) == 30 { hw("T3 PASS 3-high wall blocks walking (step-up <=1.3 enforced in-wasm)\n" as *u8) } 169 else { hw("T3 FAIL walked through the wall\n" as *u8); fails = fails + 1 } 170 171 // ---- T4 aim-ray dig/put from camera state (fresh base C) ---- 172 let bC: i64 = sys_mmap(mem_bytes()) as i64 173 start_at(bC) 174 let s30: i64 = surface_y(bC, 30, 30) 175 let s31: i64 = surface_y(bC, 30, 31) 176 tick_at(bC, 0, 0, 500) // POSITIVE mdy (mouse-back) = pitch DOWN (standard); clamps ~straight down 177 dig_at(bC) 178 var t4: i64 = 1 179 if edit_count_at(bC) != 1 { t4 = 0 } 180 var dropped: i64 = 0 181 if surface_y(bC, 30, 30) < s30 { dropped = 1 } 182 if surface_y(bC, 30, 31) < s31 { dropped = 1 } 183 if dropped == 0 { t4 = 0 } 184 put_at(bC) 185 // aiming the same way, put fills the just-dug cell -> the SAME edit key flips 2->1 (count stays 1) and the 186 // world is EXACTLY restored -- the stronger property (naive count==2 was the wrong expectation, fixed). 187 if edit_count_at(bC) < 1 { t4 = 0 } 188 var restored: i64 = 0 189 if surface_y(bC, 30, 30) == s30 { if surface_y(bC, 30, 31) == s31 { restored = 1 } } 190 if restored == 0 { t4 = 0 } 191 if t4 == 1 { hw("T4 PASS aim-ray dig lowers the surface; put restores it EXACTLY (same-cell edit, in-wasm rays)\n" as *u8) } 192 else { hw("T4 FAIL dig/put count=" as *u8); pn(edit_count_at(bC)); hw(" restored=" as *u8); pn(restored); hw("\n" as *u8); fails = fails + 1 } 193 194 // ---- T5 whole-sim determinism (fresh bases D, E) ---- 195 let bD: i64 = sys_mmap(mem_bytes()) as i64 196 let bE: i64 = sys_mmap(mem_bytes()) as i64 197 start_at(bD) 198 script(bD) 199 render_cam_at(bD) 200 let d1: i64 = fbsum(bD) 201 start_at(bE) 202 script(bE) 203 render_cam_at(bE) 204 let d2: i64 = fbsum(bE) 205 if d1 == d2 { hw("T5 PASS identical input script on two fresh worlds -> byte-identical frames\n" as *u8) } 206 else { hw("T5 FAIL sim nondeterministic\n" as *u8); fails = fails + 1 } 207 write_png((bD + fb_off()) as *i64, ww(), hh(), "knowledge/nx_mineworld_tick.png" as *u8) 208 209 // ---- T6 per-voxel texture hash varies ---- 210 var distinct: i64 = 0 211 let seen: *i64 = sys_mmap(32 * 8) as *i64 212 var k: i64 = 0 213 while k < 10 { 214 let vh: i64 = mw_h2(k * 33 + 5, k * 91 + 2, 999) % 21 215 if seen[vh] == 0 { seen[vh] = 1; distinct = distinct + 1 } 216 k = k + 1 217 } 218 if distinct >= 3 { hw("T6 PASS texture hash varies (distinct=" as *u8); pn(distinct); hw("/10 samples)\n" as *u8) } 219 else { hw("T6 FAIL texture hash flat\n" as *u8); fails = fails + 1 } 220 221 if fails == 0 { hw("VERDICT GREEN: sovereign tick 6/6 -- zero JS game logic (PNG knowledge/nx_mineworld_tick.png)\n" as *u8) } 222 else { hw("VERDICT RED fails=" as *u8); pn(fails); hw("\n" as *u8) } 223 return fails 224}