code wiki / (root) / nx_beach_contact_before_placement_t316.nx

nx_beach_contact_before_placement_t316.nx source

↩ module page · 775 lines · 30533 B

1// nx_beach_contact_gate.nx -- BEACH GROUND CONTACT: every body path that can leave feet under the 2// rendered sand has a tooth, and each tooth prints the numbers it judged (2026-09-11 beach lane). 3// Causes held here, from the 2026-09-11 fall-through diagnosis: rank 1 collision floor versus the 4// rendered field; rank 2 block-sized camera pops while walking; rank 3 an NPC buried by a window 5// shift and never walked out; rank 4 player support with feet under the field, and the stale-spawn 6// respawn that reaches it; rank 5 an NPC push across a rise; rank 6 arrivals placed on overhead 7// structures. Also a large-dt fall (15 fixed ticks per 250 ms frame from the window top) and NPCs held 8// at both window corners. A checker the current engine cannot fail is paired with a neg-control that 9// runs the SAME checker over the served rule on the same data, so a checker that cannot fire is 10// visible. Native world and fixtures only; browser visual acceptance stays with the operator. 11// license_tier: ORIGINAL 12import "nx_craft_before_placement_t316.nx" 13import "nx_gate_verdict.nx" 14import "nx_dec_emit.nx" 15 16const BCG_BLOCK_Q8: i64 = 256 // one block in Q8 world units (the engine's S_CX: 256 = one block) 17const BCG_BODY_CELLS: i64 = 2 // the two body cells mob_fits proves above a floor 18const BCG_CLAMP_BLOCKS: i64 = 2 // wc_shift's window clamp margin in blocks 19const BCG_STRUCTURE: i64 = 6 // a non-terrain solid; the legacy teeth plant the same block 20const BCG_FLAT_HQ: i64 = 1152 // the legacy teeth's flat field corner height 21const BCG_FIX_COL: i64 = 10 // the legacy teeth's fixture column 22const BCG_PATCH_REACH: i64 = 4 // half-width in blocks of a rewritten fixture field 23const BCG_WALK_TICKS: i64 = 240 // four seconds of the page's 60 Hz fixed tick per heading 24const BCG_HEADINGS: i64 = 4 // +x, -x, +z, -z 25const BCG_EDGE_BLOCKS: i64 = 4 // walks stop this far from the window edge; the shift has its own tooth 26const BCG_BURY_BLOCKS: i64 = 2 // the diagnosed burial depth the NPC rise limit never climbs 27const BCG_SHIFT_MAX: i64 = 8 // window slides allowed before the spawn must reach the clamp 28const BCG_SETTLE_TICKS: i64 = 60 // one second of fixed ticks after a placement, push or respawn 29const BCG_EDGE_TICKS: i64 = 240 // ticks the corner NPCs are observed 30const BCG_PAGE_DT_MS: i64 = 250 // the page's NXFRAME_OOR_MS frame clamp 31const BCG_TICK_US: i64 = 16667 // the page accumulator's 16.6667 ms fixed tick 32const BCG_MS_US: i64 = 1000 33const BCG_FALL_TICKS: i64 = 900 // fifteen seconds; a fall from the window top lands long before 34const BCG_PROBES: i64 = 6 // depths under the field probed by the support tooth 35const BCG_PUSH_BOX_Q8: i64 = 100 // apply2_impl's body-presence push distance 36const BCG_PUSH_GAP_Q8: i64 = SPEED+SPEED/2 // an NPC one and a half walk steps behind the player 37const BCG_PUSH_COL: i64 = WX/2 // mid-window, so no window slide fires during the push ticks 38const BCG_CANOPY_REACH: i64 = 9 // canopy half-width in blocks: summon ring 4..7 blocks, passport 3 39const BCG_PASS_ARRIVALS: i64 = 3 // wc_pass_apply spawns at most three companions 40const BCG_STALE_SINK_Q8: i64 = EYE/2 // a stale spawn height: feet under the sand, eye above it 41 42func bcg_number(value: i64, scratch: *u8) -> i64 { 43 let n: i64=nx_dec_emit_u63(scratch,0,value) 44 sys_write(1,scratch,n) 45 return 0 46} 47func bcg_abs(v: i64) -> i64 { 48 if v < 0 { return 0-v } 49 return v 50} 51// Q8 depth of feet under a floor; 0 when at or above it. 52func bcg_below(feet: i64, floor: i64) -> i64 { 53 if feet < floor { return floor-feet } 54 return 0 55} 56// A solid the terrain field does not replace, written from primitives rather than the engine's contact helper. 57func bcg_structure(base: i64, x: i64, y: i64, z: i64) -> i64 { 58 if vsolid(base,x,y,z) != 1 { return 0 } 59 if wsp(base)[P_SURF] == 1 { if wterrain(vget(base,x,y,z)) == 1 { return 0 } } 60 return 1 61} 62// Independent placement oracle: the lowest feet height at or above the terrain field whose body cells 63// hold no structure. Voxel identities fall back to the column scan. 64func bcg_place_oracle(base: i64, xq: i64, zq: i64) -> i64 { 65 if wsp(base)[P_SURF] != 1 { return wc_contact_floor_q(base,xq,zq,WY-1) } 66 var feet: i64 = wc_surface_source(base,xq,zq) 67 if feet < 0 { return -1 } 68 var cell: i64 = feet/BCG_BLOCK_Q8 69 while cell < WY && cell*BCG_BLOCK_Q8 < feet+BCG_BODY_CELLS*BCG_BLOCK_Q8 { 70 if bcg_structure(base,xq/BCG_BLOCK_Q8,cell,zq/BCG_BLOCK_Q8) == 1 { feet=(cell+1)*BCG_BLOCK_Q8 } 71 cell=cell+1 72 } 73 return feet 74} 75func bcg_arena() -> i64 { return sys_mmap(CRAFT_EXT_TOTAL) as i64 } 76func bcg_world() -> i64 { 77 let base: i64 = bcg_arena() 78 init_impl_v(base,BEACH_RELEASE_WORLD,CRAFT_DEFAULT_SEED) 79 return base 80} 81func bcg_free(base: i64) -> i64 { 82 sys_munmap(base as *u8,CRAFT_EXT_TOTAL) 83 return 0 84} 85 86func bcg_checks() -> i64 { 87 let base: i64 = sys_mmap(CRAFT_TOTAL) as i64 88 let spec: *i64 = wsp(base) 89 spec[P_SURF] = 1 90 spec[P_WATER] = 0 91 vset(base, 10, 4, 10, 5) 92 hq_set(base,10,10,1152) 93 hq_set(base,11,10,1408) 94 hq_set(base,10,11,1152) 95 hq_set(base,11,11,1408) 96 let px: i64 = 10*256+128 97 let pz: i64 = 10*256+128 98 let surface: i64 = wc_surface_source(base,px,pz) 99 let floor: i64 = wstand_here(base,px,pz)-EYE 100 if surface != 1536 { return 2 } 101 if floor != 1536 { return 3 } 102 if surface-floor != 0 { return 4 } 103 vset(base,10,8,10,6) 104 if wc_contact_floor_q(base,px,pz,WY-1) != 2304 { return 5 } 105 if wc_contact_floor_q(base,-1,pz,WY-1) != -1 { return 6 } 106 spec[P_SURF] = 0 107 if wc_contact_floor_q(base,px,pz,WY-1) != 2304 { return 7 } 108 vset(base,10,8,10,0) 109 if wc_contact_floor_q(base,px,pz,WY-1) != 1280 { return 8 } 110 spec[P_SURF] = 1 111 hq_set(base,10,11,1280) 112 hq_set(base,11,11,1536) 113 var sx: i64 = 0 114 while sx < 256 { 115 var sz: i64 = 0 116 while sz < 256 { 117 let x: i64 = 10*256+sx 118 let z: i64 = 10*256+sz 119 let expected: i64 = 1408+sx+sz/2 120 if wc_surface_source(base,x,z) != expected { return 10 } 121 if wstand_here(base,x,z)-EYE != expected { return 11 } 122 if wstand(base,x,z,expected+EYE) != expected+EYE { return 12 } 123 sz = sz+1 124 } 125 sx = sx+1 126 } 127 if wstand(base,px,pz,EYE) != -1 { return 13 } 128 if wstand(base,-1,pz,1536+EYE) != -1 { return 14 } 129 if wc_contact_floor_q(base,(WX-1)*256,pz,WY-1) != -1 { return 15 } 130 spec[P_WATER] = 8 131 vset(base,10,8,10,4) 132 if wstand_here(base,px,pz) != 9*256+EYE-96 { return 16 } 133 wc_spec(base,2) 134 var seed: i64 = 1 135 while seed <= 16 { 136 gencol(base,10,10,10,10,seed) 137 gencol(base,11,10,11,10,seed) 138 gencol(base,10,11,10,11,seed) 139 gencol(base,11,11,11,11,seed) 140 var offset: i64 = 0 141 while offset < 256 { 142 let gx: i64 = 10*256+offset 143 let gz: i64 = 10*256+255-offset 144 let field: i64 = wc_surface_source(base,gx,gz) 145 if field < 0 { return 20 } 146 if wc_contact_floor_q(base,gx,gz,WY-1) != field { return 21 } 147 offset = offset+1 148 } 149 seed=seed+1 150 } 151 let generated: i64 = sys_mmap(CRAFT_TOTAL) as i64 152 init_impl_v(generated,2,17) 153 let gs: *i64 = wst(generated) 154 if gs[S_CY] != wstand_here(generated,gs[S_CX],gs[S_CZ]) { return 30 } 155 let gm: *i64 = mobp(generated) 156 if en_count(gm) <= 0 { return 31 } 157 var ci: i64 = 0 158 while ci < en_count(gm) { 159 let handle: i64 = en_nth(gm,ci) 160 let expectedfloor: i64 = wc_contact_floor_q(generated,en_get(gm,handle,MC_X),en_get(gm,handle,MC_Z),WY-1) 161 if expectedfloor < 0 { return 32 } 162 if en_get(gm,handle,MC_Y) != expectedfloor { return 33 } 163 ci=ci+1 164 } 165 let initial: *i64 = sys_mmap(MOB_CAP*16) as *i64 166 let observed: *i64 = sys_mmap(MOB_CAP*24) as *i64 167 let actorCount: i64 = en_count(gm) 168 let numberText: *u8 = sys_mmap(NX_DEC_EMIT_MAX_BYTES) 169 ci=0 170 while ci < en_count(gm) { 171 let handle: i64 = en_nth(gm,ci) 172 observed[ci*3]=handle 173 initial[ci*2]=en_get(gm,handle,MC_X) 174 initial[ci*2+1]=en_get(gm,handle,MC_Z) 175 ci=ci+1 176 } 177 var frame: i64 = 0 178 while frame < 120 { 179 gs[S_T]=gs[S_T]+1 180 mob_tick(generated) 181 if en_count(gm) != actorCount { return 37 } 182 ci=0 183 while ci < en_count(gm) { 184 let handle: i64 = en_nth(gm,ci) 185 if handle != observed[ci*3] { return 38 } 186 let floorNow: i64 = wc_contact_floor_q(generated,en_get(gm,handle,MC_X),en_get(gm,handle,MC_Z),WY-1) 187 if floorNow < 0 { return 34 } 188 if en_get(gm,handle,MC_Y) < floorNow { return 35 } 189 let clearance: i64 = en_get(gm,handle,MC_Y)-floorNow 190 if clearance > observed[ci*3+2] { observed[ci*3+2]=clearance } 191 if en_get(gm,handle,MC_X) != initial[ci*2] || en_get(gm,handle,MC_Z) != initial[ci*2+1] { observed[ci*3+1]=observed[ci*3+1]+1 } 192 ci=ci+1 193 } 194 frame=frame+1 195 } 196 var moved: i64 = 0 197 var stationary: i64 = 0 198 ci=0 199 while ci < en_count(gm) { 200 let handle: i64 = en_nth(gm,ci) 201 if observed[ci*3+1] > 0 { moved=moved+1 } else { stationary=stationary+1 } 202 sys_write(1,"ACTOR handle=" as *u8,13); bcg_number(handle,numberText) 203 sys_write(1," displaced_frames=" as *u8,18); bcg_number(observed[ci*3+1],numberText) 204 sys_write(1," max_clearance_q8=" as *u8,18); bcg_number(observed[ci*3+2],numberText) 205 sys_write(1,"\n" as *u8,1) 206 ci=ci+1 207 } 208 sys_write(1,"CAST moved=" as *u8,11); bcg_number(moved,numberText) 209 sys_write(1," stationary=" as *u8,12); bcg_number(stationary,numberText) 210 sys_write(1,"\n" as *u8,1) 211 if moved == 0 { return 36 } 212 let trapped: i64 = sys_mmap(CRAFT_TOTAL) as i64 213 init_impl_v(trapped,2,17) 214 let tm: *i64 = mobp(trapped) 215 let ts: *i64 = wst(trapped) 216 let tn: *i64 = (trapped+O_NEED) as *i64 217 let savedGait: *i64 = sys_mmap(MOB_CAP*8) as *i64 218 ci=0 219 while ci < en_count(tm) { 220 let h: i64 = en_nth(tm,ci) 221 savedGait[ci]=tn[ci*4+WC_NEED_GAIT] 222 let tx: i64 = en_get(tm,h,MC_X)>>8 223 let tz: i64 = en_get(tm,h,MC_Z)>>8 224 let ty: i64 = (en_get(tm,h,MC_Y)>>8)+1 225 var ax: i64 = tx-1 226 while ax <= tx+1 { 227 var az: i64 = tz-1 228 while az <= tz+1 { 229 var ay: i64 = ty 230 while ay < WY { vset(trapped,ax,ay,az,6); ay=ay+1 } 231 az=az+1 232 } 233 ax=ax+1 234 } 235 ci=ci+1 236 } 237 ts[S_T]=ts[S_T]+1 238 mob_tick(trapped) 239 let applied: *i64 = (trapped+O_MOBAUX) as *i64 240 ci=0 241 while ci < en_count(tm) { 242 if applied[ci*3] != 0 || applied[ci*3+1] != 0 { return 39 } 243 if tn[ci*4+WC_NEED_GAIT] != savedGait[ci] { return 40 } 244 ci=ci+1 245 } 246 return 0 247} 248 249// RANK 1: the collision floor is the rendered field on every structure-free column of the served seed. 250func bcg_census(ctr: *i64) -> i64 { 251 let base: i64 = bcg_world() 252 var checked: i64 = 0 253 var fieldOnly: i64 = 0 254 var structured: i64 = 0 255 var mismatch: i64 = 0 256 var servedBelow: i64 = 0 257 var servedBlock: i64 = 0 258 var servedEye: i64 = 0 259 var servedMax: i64 = 0 260 var x: i64 = 0 261 while x < WX-1 { 262 var z: i64 = 0 263 while z < WZ-1 { 264 let xq: i64 = x*BCG_BLOCK_Q8+BCG_BLOCK_Q8/2 265 let zq: i64 = z*BCG_BLOCK_Q8+BCG_BLOCK_Q8/2 266 let field: i64 = wc_surface_source(base,xq,zq) 267 let contact: i64 = wc_contact_floor_q(base,xq,zq,WY-1) 268 checked=checked+1 269 if contact > field { structured=structured+1 } else { 270 fieldOnly=fieldOnly+1 271 if contact != field { mismatch=mismatch+1 } 272 } 273 let top: i64 = wground(base,x,z) 274 if top >= 0 { 275 let gap: i64 = field-(top+1)*BCG_BLOCK_Q8 276 if gap > 0 { servedBelow=servedBelow+1 } 277 if gap > BCG_BLOCK_Q8 { servedBlock=servedBlock+1 } 278 if gap > EYE { servedEye=servedEye+1 } 279 if gap > servedMax { servedMax=gap } 280 } 281 z=z+1 282 } 283 x=x+1 284 } 285 gv_kv("rank1_columns_checked",checked) 286 gv_kv("rank1_field_only_columns",fieldOnly) 287 gv_kv("rank1_structure_columns",structured) 288 gv_kv("rank1_partition_sum",fieldOnly+structured) 289 gv_kv("rank1_contact_field_mismatch_columns",mismatch) 290 gv_kv("served_rule_feet_under_field_columns",servedBelow) 291 gv_kv("served_rule_gap_over_one_block_columns",servedBlock) 292 gv_kv("served_rule_gap_over_eye_height_columns",servedEye) 293 gv_kv("served_rule_gap_max_q8",servedMax) 294 gv_check("rank1 contact floor equals the rendered field on every structure-free column of world 2 seed 20260728",(checked > 0 && fieldOnly+structured == checked && mismatch == 0) as i64,ctr) 295 gv_check("neg-control-served-voxel-top-rule-puts-feet-under-the-field-on-the-same-columns",(servedBelow > 0) as i64,ctr) 296 bcg_free(base) 297 return 0 298} 299 300// RANK 2: walking the served seed in four headings never pops the camera by a block, never leaves the 301// feet under the field, and a grounded tick always rests exactly on contact support. 302func bcg_walk(ctr: *i64) -> i64 { 303 let base: i64 = bcg_world() 304 let s: *i64 = wst(base) 305 let edgeLo: i64 = BCG_EDGE_BLOCKS*BCG_BLOCK_Q8 306 let edgeHiX: i64 = (WX-BCG_EDGE_BLOCKS)*BCG_BLOCK_Q8 307 let edgeHiZ: i64 = (WZ-BCG_EDGE_BLOCKS)*BCG_BLOCK_Q8 308 var ticks: i64 = 0 309 var movedTicks: i64 = 0 310 var groundedTicks: i64 = 0 311 var below: i64 = 0 312 var pops: i64 = 0 313 var groundedMismatch: i64 = 0 314 var maxRise: i64 = 0 315 var maxDrop: i64 = 0 316 var servedBelow: i64 = 0 317 var servedPops: i64 = 0 318 var heading: i64 = 0 319 while heading < BCG_HEADINGS { 320 s[S_CX]=s[S_SPX]; s[S_CY]=s[S_SPY]; s[S_CZ]=s[S_SPZ]; s[S_VY]=0; s[S_GROUNDED]=1 321 var mx: i64 = 0 322 var mz: i64 = 0 323 if heading == 0 { mx=SPEED } 324 if heading == 1 { mx=0-SPEED } 325 if heading == 2 { mz=SPEED } 326 if heading == 3 { mz=0-SPEED } 327 var servedPrev: i64 = -1 328 var walking: i64 = 1 329 var t: i64 = 0 330 while walking == 1 && t < BCG_WALK_TICKS { 331 let nx: i64 = s[S_CX]+mx 332 let nz: i64 = s[S_CZ]+mz 333 if nx < edgeLo || nz < edgeLo || nx > edgeHiX || nz > edgeHiZ { walking=0 } else { 334 let px: i64 = s[S_CX] 335 let pz: i64 = s[S_CZ] 336 let py: i64 = s[S_CY] 337 wc_player_motion(base,mx,mz,0) 338 ticks=ticks+1 339 if s[S_CX] != px || s[S_CZ] != pz { movedTicks=movedTicks+1 } 340 let field: i64 = wc_surface_source(base,s[S_CX],s[S_CZ]) 341 if field >= 0 { if bcg_below(s[S_CY]-EYE,field) > 0 { below=below+1 } } 342 let dy: i64 = s[S_CY]-py 343 if bcg_abs(dy) >= BCG_BLOCK_Q8 { pops=pops+1 } 344 if dy > maxRise { maxRise=dy } 345 if 0-dy > maxDrop { maxDrop=0-dy } 346 if s[S_GROUNDED] == 1 { 347 groundedTicks=groundedTicks+1 348 if wc_player_support(base,s[S_CX],s[S_CZ],s[S_CY]-EYE) != s[S_CY] { groundedMismatch=groundedMismatch+1 } 349 } 350 let top: i64 = wground(base,s[S_CX]/BCG_BLOCK_Q8,s[S_CZ]/BCG_BLOCK_Q8) 351 if top >= 0 { 352 let served: i64 = (top+1)*BCG_BLOCK_Q8+EYE 353 if field >= 0 { if bcg_below(served-EYE,field) > 0 { servedBelow=servedBelow+1 } } 354 if servedPrev >= 0 { if bcg_abs(served-servedPrev) >= BCG_BLOCK_Q8 { servedPops=servedPops+1 } } 355 servedPrev=served 356 } 357 t=t+1 358 } 359 } 360 heading=heading+1 361 } 362 gv_kv("rank2_walk_ticks",ticks) 363 gv_kv("rank2_walk_moved_ticks",movedTicks) 364 gv_kv("rank2_walk_grounded_ticks",groundedTicks) 365 gv_kv("rank2_walk_max_rise_per_tick_q8",maxRise) 366 gv_kv("rank2_walk_max_drop_per_tick_q8",maxDrop) 367 gv_kv("served_rule_walk_ticks_feet_under_field",servedBelow) 368 gv_kv("served_rule_walk_block_pops",servedPops) 369 gv_check("rank2 walk fixture moved the player and grounded it on this seed",(movedTicks > 0 && groundedTicks > 0) as i64,ctr) 370 gv_check_eq("rank2 walk ticks with feet under the rendered field",below,0,ctr) 371 gv_check_eq("rank2 walk ticks with a block-sized camera pop or drop",pops,0,ctr) 372 gv_check_eq("rank2 walk grounded ticks whose height differs from contact support",groundedMismatch,0,ctr) 373 gv_check("neg-control-served-voxel-top-rule-pops-a-block-on-the-same-walk",(servedPops > 0) as i64,ctr) 374 bcg_free(base) 375 return 0 376} 377 378// RANK 3: a window shift clamps an NPC onto another column and must not leave her buried; her own tick 379// must lift a girl found under her floor. 380func bcg_shift_burial(ctr: *i64) -> i64 { 381 let base: i64 = bcg_world() 382 let m: *i64 = mobp(base) 383 let gs: *i64 = wst(base) 384 let h: i64 = en_nth(m,0) 385 let hz: i64 = en_get(m,h,MC_Z) 386 let landing: i64 = (BCG_CLAMP_BLOCKS+SHIFT_STRIDE)*BCG_BLOCK_Q8 387 let planned: i64 = bcg_place_oracle(base,landing,hz) 388 en_set(m,h,MC_X,BCG_BLOCK_Q8+BCG_BLOCK_Q8/2) 389 en_set(m,h,MC_Y,planned-BCG_BURY_BLOCKS*BCG_BLOCK_Q8) 390 wc_shift(base,SHIFT_STRIDE,0) 391 let seatX: i64 = en_get(m,h,MC_X) 392 let floorAfter: i64 = bcg_place_oracle(base,seatX,en_get(m,h,MC_Z)) 393 let yAfter: i64 = en_get(m,h,MC_Y) 394 var worst: i64 = 0 395 var t: i64 = 0 396 while t < BCG_SETTLE_TICKS { 397 gs[S_T]=gs[S_T]+1 398 mob_tick(base) 399 let d: i64 = bcg_below(en_get(m,h,MC_Y),wc_surface_source(base,en_get(m,h,MC_X),en_get(m,h,MC_Z))) 400 if d > worst { worst=d } 401 t=t+1 402 } 403 gv_kv("rank3_shift_landing_x_q8",seatX) 404 gv_kv("rank3_planned_floor_q8",planned) 405 gv_kv("rank3_floor_after_shift_q8",floorAfter) 406 gv_kv("rank3_npc_y_after_shift_q8",yAfter) 407 gv_kv("rank3_worst_under_field_after_shift_q8",worst) 408 gv_check("rank3 shift fixture clamped the npc onto a column whose floor is two blocks above her feet",(seatX == BCG_CLAMP_BLOCKS*BCG_BLOCK_Q8 && planned >= 0 && floorAfter == planned) as i64,ctr) 409 gv_check_eq("rank3 npc q8 under her floor straight after the window shift",bcg_below(yAfter,floorAfter),0,ctr) 410 gv_check_eq("rank3 npc worst q8 under the field over the ticks after the shift",worst,0,ctr) 411 bcg_free(base) 412 let own: i64 = bcg_world() 413 let om: *i64 = mobp(own) 414 let os: *i64 = wst(own) 415 let oh: i64 = en_nth(om,0) 416 let ownFloor: i64 = bcg_place_oracle(own,en_get(om,oh,MC_X),en_get(om,oh,MC_Z)) 417 en_set(om,oh,MC_Y,ownFloor-BCG_BURY_BLOCKS*BCG_BLOCK_Q8) 418 os[S_T]=os[S_T]+1 419 mob_tick(own) 420 let lifted: i64 = bcg_below(en_get(om,oh,MC_Y),wc_surface_source(own,en_get(om,oh,MC_X),en_get(om,oh,MC_Z))) 421 gv_kv("rank3_own_column_floor_q8",ownFloor) 422 gv_kv("rank3_own_column_under_field_after_tick_q8",lifted) 423 gv_check_eq("rank3 buried npc q8 under the field after one tick of her own",lifted,0,ctr) 424 bcg_free(own) 425 return 0 426} 427 428// RANK 4: player support never discards the field above the feet. Feet under a flat field at six 429// depths are lifted onto it within one tick and held; a body above the field falls and lands on it. 430func bcg_support_depths(ctr: *i64) -> i64 { 431 let base: i64 = bcg_arena() 432 let spec: *i64 = wsp(base) 433 spec[P_SURF]=1 434 spec[P_WATER]=0 435 var cx: i64 = BCG_FIX_COL-BCG_PATCH_REACH 436 while cx <= BCG_FIX_COL+BCG_PATCH_REACH { 437 var cz: i64 = BCG_FIX_COL-BCG_PATCH_REACH 438 while cz <= BCG_FIX_COL+BCG_PATCH_REACH { hq_set(base,cx,cz,BCG_FLAT_HQ); cz=cz+1 } 439 cx=cx+1 440 } 441 let s: *i64 = wst(base) 442 let p: i64 = BCG_FIX_COL*BCG_BLOCK_Q8+BCG_BLOCK_Q8/2 443 let field: i64 = wc_surface_source(base,p,p) 444 var failures: i64 = 0 445 var firstDepth: i64 = -1 446 var firstEye: i64 = 0 447 var i: i64 = 0 448 while i < BCG_PROBES { 449 var depth: i64 = 1 450 if i == 1 { depth=BCG_BLOCK_Q8-1 } 451 if i == 2 { depth=BCG_BLOCK_Q8 } 452 if i == 3 { depth=EYE-1 } 453 if i == 4 { depth=EYE } 454 if i == 5 { depth=EYE+BCG_BLOCK_Q8 } 455 s[S_CX]=p; s[S_CZ]=p; s[S_CY]=field+EYE-depth; s[S_VY]=0; s[S_GROUNDED]=0 456 var bad: i64 = 0 457 var t: i64 = 0 458 while t < BCG_SETTLE_TICKS { 459 wc_player_vertical_apply(base,0) 460 if s[S_CY] != field+EYE { bad=1 } 461 t=t+1 462 } 463 if s[S_GROUNDED] != 1 { bad=1 } 464 if bad == 1 { 465 failures=failures+1 466 if firstDepth < 0 { firstDepth=depth; firstEye=s[S_CY] } 467 } 468 i=i+1 469 } 470 s[S_CX]=p; s[S_CZ]=p; s[S_CY]=field+EYE+BCG_BLOCK_Q8; s[S_VY]=0; s[S_GROUNDED]=0 471 var t2: i64 = 0 472 while t2 < BCG_SETTLE_TICKS { wc_player_vertical_apply(base,0); t2=t2+1 } 473 gv_kv("rank4_field_q8",field) 474 gv_kv("rank4_first_failing_depth_q8",firstDepth) 475 gv_kv("rank4_first_failing_eye_y_q8",firstEye) 476 gv_kv("rank4_control_eye_y_q8",s[S_CY]) 477 gv_check_eq("rank4 fixture field height q8",field,BCG_FLAT_HQ+BCG_BLOCK_Q8,ctr) 478 gv_check_eq("rank4 probe depths under the field not lifted onto it and held",failures,0,ctr) 479 gv_check_eq("rank4 control body a block above the field lands on it (q8 error)",bcg_abs(s[S_CY]-(field+EYE)),0,ctr) 480 bcg_free(base) 481 return 0 482} 483 484// RANK 4 entry: after window slides clamp the spawn column, a stale stored height must not respawn the 485// player under the sand (the H key and the void rescue share wc_respawn). 486func bcg_respawn(ctr: *i64) -> i64 { 487 let base: i64 = bcg_world() 488 let s: *i64 = wst(base) 489 let startX: i64 = s[S_SPX] 490 var shifts: i64 = 0 491 while shifts < BCG_SHIFT_MAX && s[S_SPX] > BCG_CLAMP_BLOCKS*BCG_BLOCK_Q8 { 492 wc_shift(base,SHIFT_STRIDE,0) 493 shifts=shifts+1 494 } 495 let spawnFloor: i64 = bcg_place_oracle(base,s[S_SPX],s[S_SPZ]) 496 s[S_SPY]=spawnFloor+EYE-BCG_STALE_SINK_Q8 497 wc_respawn(base) 498 let eyeAfterRespawn: i64 = s[S_CY] 499 var below: i64 = 0 500 var worst: i64 = 0 501 var t: i64 = 0 502 while t < BCG_SETTLE_TICKS { 503 wc_player_motion(base,0,0,0) 504 let d: i64 = bcg_below(s[S_CY]-EYE,wc_surface_source(base,s[S_CX],s[S_CZ])) 505 if d > 0 { below=below+1 } 506 if d > worst { worst=d } 507 t=t+1 508 } 509 gv_kv("rank4_respawn_start_spawn_x_q8",startX) 510 gv_kv("rank4_respawn_shifts",shifts) 511 gv_kv("rank4_respawn_clamped_spawn_x_q8",s[S_SPX]) 512 gv_kv("rank4_respawn_spawn_floor_q8",spawnFloor) 513 gv_kv("rank4_respawn_eye_after_respawn_q8",eyeAfterRespawn) 514 gv_kv("rank4_respawn_worst_feet_under_field_q8",worst) 515 gv_check("rank4 respawn fixture clamped the spawn column and found its floor",(shifts > 0 && s[S_SPX] == BCG_CLAMP_BLOCKS*BCG_BLOCK_Q8 && spawnFloor >= 0) as i64,ctr) 516 gv_check_eq("rank4 respawn ticks with feet under the field after the clamp",below,0,ctr) 517 bcg_free(base) 518 return 0 519} 520 521// NPCs held at both window corners: the field is sampled where they stand and they never stand under it. 522func bcg_edge_npc(ctr: *i64) -> i64 { 523 let base: i64 = bcg_world() 524 let m: *i64 = mobp(base) 525 let gs: *i64 = wst(base) 526 let maxX: i64 = (WX-BCG_CLAMP_BLOCKS)*BCG_BLOCK_Q8 527 let maxZ: i64 = (WZ-BCG_CLAMP_BLOCKS)*BCG_BLOCK_Q8 528 let minQ: i64 = BCG_CLAMP_BLOCKS*BCG_BLOCK_Q8 529 let hHi: i64 = en_nth(m,0) 530 let hLo: i64 = en_nth(m,1) 531 en_set(m,hHi,MC_X,maxX) 532 en_set(m,hHi,MC_Z,maxZ) 533 en_set(m,hHi,MC_Y,bcg_place_oracle(base,maxX,maxZ)) 534 en_set(m,hLo,MC_X,minQ) 535 en_set(m,hLo,MC_Z,minQ) 536 en_set(m,hLo,MC_Y,bcg_place_oracle(base,minQ,minQ)) 537 var invalid: i64 = 0 538 var below: i64 = 0 539 var moved: i64 = 0 540 var farX: i64 = 0 541 var nearX: i64 = maxX 542 var t: i64 = 0 543 while t < BCG_EDGE_TICKS { 544 gs[S_T]=gs[S_T]+1 545 mob_tick(base) 546 var j: i64 = 0 547 while j < 2 { 548 var hh: i64 = hHi 549 var startX: i64 = maxX 550 var startZ: i64 = maxZ 551 if j == 1 { hh=hLo; startX=minQ; startZ=minQ } 552 let ex: i64 = en_get(m,hh,MC_X) 553 let ez: i64 = en_get(m,hh,MC_Z) 554 let field: i64 = wc_surface_source(base,ex,ez) 555 if field < 0 { invalid=invalid+1 } else { if en_get(m,hh,MC_Y) < field { below=below+1 } } 556 if ex != startX || ez != startZ { moved=moved+1 } 557 if ex > farX { farX=ex } 558 if ex < nearX { nearX=ex } 559 j=j+1 560 } 561 t=t+1 562 } 563 gv_kv("edge_far_x_q8",farX) 564 gv_kv("edge_near_x_q8",nearX) 565 gv_kv("edge_moved_observations",moved) 566 gv_kv("edge_unsampled_observations",invalid) 567 gv_kv("edge_under_field_observations",below) 568 gv_check("edge corner npcs observed away from their start",(moved > 0) as i64,ctr) 569 gv_check_eq("edge observations where a corner npc stood where the field cannot be sampled",invalid,0,ctr) 570 gv_check_eq("edge observations where a corner npc stood under the field",below,0,ctr) 571 gv_check("neg-control-the-field-sampler-refuses-the-last-window-column",(wc_surface_source(base,(WX-1)*BCG_BLOCK_Q8,maxZ) < 0) as i64,ctr) 572 bcg_free(base) 573 return 0 574} 575 576// RANK 5: an NPC body pushing the player across a one-block rise never leaves the feet under the field. 577func bcg_push(ctr: *i64) -> i64 { 578 let base: i64 = bcg_world() 579 let spec: *i64 = wsp(base) 580 spec[P_WATER]=0 581 let s: *i64 = wst(base) 582 var cx: i64 = BCG_PUSH_COL-BCG_PATCH_REACH 583 while cx <= BCG_PUSH_COL+BCG_PATCH_REACH { 584 var cz: i64 = BCG_PUSH_COL-BCG_PATCH_REACH 585 while cz <= BCG_PUSH_COL+BCG_PATCH_REACH { 586 var hqv: i64 = BCG_FLAT_HQ 587 if cx > BCG_PUSH_COL { hqv=BCG_FLAT_HQ+BCG_BLOCK_Q8 } 588 hq_set(base,cx,cz,hqv) 589 var y: i64 = 0 590 while y < WY { if bcg_structure(base,cx,y,cz) == 1 { vset(base,cx,y,cz,0) }; y=y+1 } 591 cz=cz+1 592 } 593 cx=cx+1 594 } 595 let px: i64 = BCG_PUSH_COL*BCG_BLOCK_Q8+BCG_BLOCK_Q8/2 596 let pz: i64 = BCG_PUSH_COL*BCG_BLOCK_Q8+BCG_BLOCK_Q8/2 597 s[S_CX]=px; s[S_CZ]=pz; s[S_CY]=wc_surface_source(base,px,pz)+EYE; s[S_VY]=0; s[S_GROUNDED]=1 598 s[S_SPX]=px; s[S_SPY]=s[S_CY]; s[S_SPZ]=pz 599 let m: *i64 = mobp(base) 600 en_init(m,MOB_CAP,MOB_NCOMP) 601 let h: i64 = en_spawn(m) 602 en_set(m,h,MC_X,px-BCG_PUSH_GAP_Q8) 603 en_set(m,h,MC_Z,pz) 604 en_set(m,h,MC_Y,s[S_CY]-EYE) 605 let startFeet: i64 = s[S_CY]-EYE 606 let servedGap: i64 = bcg_below(startFeet,wc_surface_source(base,px-BCG_PUSH_GAP_Q8+BCG_PUSH_BOX_Q8,pz)) 607 var below: i64 = 0 608 var worst: i64 = 0 609 var farX: i64 = px 610 var t: i64 = 0 611 while t < BCG_SETTLE_TICKS { 612 apply2_impl(base,0,0,0,0,0,0,0,0,0) 613 let d: i64 = bcg_below(s[S_CY]-EYE,wc_surface_source(base,s[S_CX],s[S_CZ])) 614 if d > 0 { below=below+1 } 615 if d > worst { worst=d } 616 if s[S_CX] > farX { farX=s[S_CX] } 617 t=t+1 618 } 619 gv_kv("rank5_start_x_q8",px) 620 gv_kv("rank5_far_x_q8",farX) 621 gv_kv("rank5_worst_feet_under_field_q8",worst) 622 gv_kv("served_rule_push_feet_under_field_q8",servedGap) 623 gv_check("rank5 push fixture moved the player across the rise",(farX > px) as i64,ctr) 624 gv_check_eq("rank5 push ticks with feet under the field",below,0,ctr) 625 gv_check("neg-control-served-push-without-a-stand-check-leaves-feet-under-the-rise",(servedGap > 0) as i64,ctr) 626 bcg_free(base) 627 return 0 628} 629 630// Plant one structure cell above the body span of every field point in a column, so a body standing on 631// the field fits beneath it while a scan from the sky meets the canopy first. 632func bcg_canopy(base: i64, cx: i64, cz: i64) -> i64 { 633 var high: i64 = hq_get(base,cx,cz) 634 if hq_get(base,cx+1,cz) > high { high=hq_get(base,cx+1,cz) } 635 if hq_get(base,cx,cz+1) > high { high=hq_get(base,cx,cz+1) } 636 if hq_get(base,cx+1,cz+1) > high { high=hq_get(base,cx+1,cz+1) } 637 let fieldTop: i64 = high+BCG_BLOCK_Q8 638 let cell: i64 = (fieldTop+BCG_BODY_CELLS*BCG_BLOCK_Q8+BCG_BLOCK_Q8-1)/BCG_BLOCK_Q8 639 vset(base,cx,cell,cz,BCG_STRUCTURE) 640 return cell 641} 642 643// RANK 6: summoned girls and passport arrivals stand on the lowest body-fitting floor, never on a canopy. 644func bcg_placement(ctr: *i64) -> i64 { 645 let base: i64 = bcg_world() 646 let s: *i64 = wst(base) 647 let m: *i64 = mobp(base) 648 let pcx: i64 = s[S_CX]/BCG_BLOCK_Q8 649 let pcz: i64 = s[S_CZ]/BCG_BLOCK_Q8 650 var planted: i64 = 0 651 var cx: i64 = pcx-BCG_CANOPY_REACH 652 while cx <= pcx+BCG_CANOPY_REACH { 653 var cz: i64 = pcz-BCG_CANOPY_REACH 654 while cz <= pcz+BCG_CANOPY_REACH { 655 if cx >= BCG_CLAMP_BLOCKS && cz >= BCG_CLAMP_BLOCKS && cx < WX-BCG_CLAMP_BLOCKS && cz < WZ-BCG_CLAMP_BLOCKS { 656 bcg_canopy(base,cx,cz) 657 planted=planted+1 658 } 659 cz=cz+1 660 } 661 cx=cx+1 662 } 663 let summoned: i64 = summon_impl(base) 664 var covered: i64 = 0 665 var misplaced: i64 = 0 666 var k: i64 = 0 667 while k < en_count(m) { 668 let h: i64 = en_nth(m,k) 669 let x: i64 = en_get(m,h,MC_X) 670 let z: i64 = en_get(m,h,MC_Z) 671 if bcg_abs(x/BCG_BLOCK_Q8-pcx) <= BCG_CANOPY_REACH && bcg_abs(z/BCG_BLOCK_Q8-pcz) <= BCG_CANOPY_REACH { 672 covered=covered+1 673 if en_get(m,h,MC_Y) != bcg_place_oracle(base,x,z) { misplaced=misplaced+1 } 674 } 675 k=k+1 676 } 677 let pass: *i64 = passp(base) 678 pass[0]=PASS_MAGIC 679 pass[1]=1 680 pass[11]=BCG_PASS_ARRIVALS 681 var pc: i64 = 0 682 while pc < BCG_PASS_ARRIVALS { pass[12+pc*3]=pc; pass[13+pc*3]=0; pass[14+pc*3]=pc+1; pc=pc+1 } 683 pass[21]=wc_pass_ck(pass) 684 let before: i64 = en_count(m) 685 let passRc: i64 = wc_pass_apply(base) 686 let arrivals: i64 = en_count(m)-before 687 var passMisplaced: i64 = 0 688 k=before 689 while k < en_count(m) { 690 let h: i64 = en_nth(m,k) 691 if en_get(m,h,MC_Y) != bcg_place_oracle(base,en_get(m,h,MC_X),en_get(m,h,MC_Z)) { passMisplaced=passMisplaced+1 } 692 k=k+1 693 } 694 gv_kv("rank6_canopy_columns",planted) 695 gv_kv("rank6_cast_after_summon",summoned) 696 gv_kv("rank6_girls_under_canopies",covered) 697 gv_kv("rank6_summon_misplaced",misplaced) 698 gv_kv("rank6_passport_rc",passRc) 699 gv_kv("rank6_passport_arrivals",arrivals) 700 gv_kv("rank6_passport_misplaced",passMisplaced) 701 gv_check("rank6 placement fixture planted canopies over summoned and arriving girls",(planted > 0 && covered > 0 && arrivals > 0) as i64,ctr) 702 gv_check_eq("rank6 summoned girls not on the lowest body-fitting floor",misplaced,0,ctr) 703 gv_check_eq("rank6 passport arrivals not on the lowest body-fitting floor",passMisplaced,0,ctr) 704 bcg_free(base) 705 return 0 706} 707 708// LARGE DT: the page clamps a frame to 250 ms and runs fixed ticks; 15 ticks per frame is the uncapped 709// worst. A fall from the window top never passes under the field and rests exactly on support. 710func bcg_fall(ctr: *i64) -> i64 { 711 let base: i64 = bcg_world() 712 let s: *i64 = wst(base) 713 let perFrame: i64 = (BCG_PAGE_DT_MS*BCG_MS_US+BCG_TICK_US-1)/BCG_TICK_US 714 let field0: i64 = wc_surface_source(base,s[S_CX],s[S_CZ]) 715 let start: i64 = (WY-BCG_BODY_CELLS)*BCG_BLOCK_Q8 716 s[S_CY]=start 717 s[S_VY]=0 718 s[S_GROUNDED]=0 719 var below: i64 = 0 720 var overspeed: i64 = 0 721 var landed: i64 = -1 722 var ghostY: i64 = start 723 var ghostV: i64 = 0 724 var ghostBelow: i64 = 0 725 var t: i64 = 0 726 while t < BCG_FALL_TICKS { 727 var f: i64 = 0 728 while f < perFrame { 729 wc_player_motion(base,0,0,0) 730 if bcg_below(s[S_CY]-EYE,wc_surface_source(base,s[S_CX],s[S_CZ])) > 0 { below=below+1 } 731 if s[S_VY] < 0-VTERM { overspeed=overspeed+1 } 732 if landed < 0 && s[S_GROUNDED] == 1 { landed=t } 733 ghostV=ghostV-GRAV 734 if ghostV < 0-VTERM { ghostV=0-VTERM } 735 ghostY=ghostY+ghostV 736 if bcg_below(ghostY-EYE,field0) > 0 { ghostBelow=ghostBelow+1 } 737 f=f+1 738 t=t+1 739 } 740 } 741 let support: i64 = wc_player_support(base,s[S_CX],s[S_CZ],s[S_CY]-EYE) 742 gv_kv("largedt_ticks_per_frame",perFrame) 743 gv_kv("largedt_field_q8",field0) 744 gv_kv("largedt_landed_tick",landed) 745 gv_kv("largedt_final_eye_q8",s[S_CY]) 746 gv_kv("largedt_support_q8",support) 747 gv_kv("largedt_unsupported_integrator_under_field_ticks",ghostBelow) 748 gv_check_eq("large-dt fall ticks with feet under the field at 15 fixed ticks per 250 ms frame",below,0,ctr) 749 gv_check_eq("large-dt fall ticks faster than terminal velocity",overspeed,0,ctr) 750 gv_check("large-dt fall landed and rests exactly on contact support",(landed >= 0 && s[S_GROUNDED] == 1 && s[S_CY] == support) as i64,ctr) 751 s[S_CY]=field0+EYE+1 752 s[S_VY]=0-VTERM 753 s[S_GROUNDED]=0 754 wc_player_motion(base,0,0,0) 755 gv_check_eq("terminal-velocity tick from one q8 above the field lands on it (q8 error)",bcg_abs(s[S_CY]-(field0+EYE)),0,ctr) 756 gv_check("neg-control-an-integrator-without-support-falls-through-the-field-on-the-same-fall",(ghostBelow > 0) as i64,ctr) 757 bcg_free(base) 758 return 0 759} 760 761func main() -> i64 { 762 let c: *i64 = gv_ctr() 763 let result: i64 = bcg_checks() 764 gv_check_eq("main-world ground and cast contact regression exit code",result,0,c) 765 bcg_census(c) 766 bcg_walk(c) 767 bcg_shift_burial(c) 768 bcg_support_depths(c) 769 bcg_respawn(c) 770 bcg_edge_npc(c) 771 bcg_push(c) 772 bcg_placement(c) 773 bcg_fall(c) 774 return gv_verdict("BEACH-CONTACT",c,"Native main world and fixtures; browser visual acceptance is separate.") 775}