code wiki / (root) / nx_beach_pose_pair_gate_t123.nx

nx_beach_pose_pair_gate_t123.nx source

↩ module page · 145 lines · 8453 B

1// Private qualification of the existing native facing owner. 2import "_hdl_build/nx_wasm_craft_residency_t44.nx" 3import "nx_gate_verdict.nx" 4import "nx_game_page_artifact_lib.nx" 5import "nx_game_pair_layout_lib.nx" 6import "nx_wasm_layout_read_lib.nx" 7func facing_legacy_step(hdg: i64, dx: i64, dz: i64) -> i64 { 8 var ax: i64 = dx 9 if ax < 0 { ax = 0 - ax } 10 var az: i64 = dz 11 if az < 0 { az = 0 - az } 12 if ax + az == 0 { return hdg } // no intent, no turn: she is standing 13 let mag: i64 = sd_isqrt(dx*dx + dz*dz) 14 if mag <= 0 { return hdg } 15 let fx: i64 = it_sin4096(hdg % (2*IT_PI)) 16 let fz: i64 = it_cos4096(hdg % (2*IT_PI)) 17 // cross and dot of forward (fx4096, unit) with the desired step (q8, magnitude mag) 18 // ⚠NOT PRE-DIVIDED BY 4096. Dividing here first would floor cr to single digits at a mob's 19 // 4-7 q8 step and quantise the whole controller into a handful of levels -- which is the 20 // stutter this function exists to remove, reintroduced inside the fix. Both products stay in 21 // 4096*q8 units and the one division happens at the end, against mag*4096. 22 let cr: i64 = fx*dz - fz*dx // 4096 * mag * sin(error) 23 let dt: i64 = fx*dx + fz*dz // 4096 * mag * cos(error) 24 // quarter turn per stride, pro-rated by the ground this tick actually covers 25 let mx: i64 = mag*WC_TURN_PER_STRIDE/WC_STRIDE_Q8 26 // SIGN, AND IT WAS WRONG FIRST TIME. The (x,z) cross product fx*dz - fz*dx measures rotation 27 // from +x toward +z, and this engine yaw runs the OTHER way round: forward is (sin yaw, 28 // cos yaw), so increasing yaw turns from +z toward +x. The cross therefore carries 29 // -sin(error), not +sin(error), and the correction is its NEGATION. 30 // Settled against a case with an unambiguous answer rather than by staring at it: facing +z 31 // (yaw 0) with the target at +x plainly needs yaw to INCREASE, and there the cross comes out 32 // NEGATIVE -- so the turn is -cr. 33 // WHAT THE WRONG SIGN DID, because it is not the failure anyone would predict: it does not 34 // wobble or overshoot, it makes facing-directly-AWAY-from-the-target a stable point, so she 35 // walks backwards away from where she is going and looks perfectly calm doing it. Gate tooth 36 // T82 caught it as a 2-cycle that never converged out of a half-turn reversal. 37 var st: i64 = 0 - mx*cr/(mag*WATER_MAGIC_4096) // = mx*sin(error): proportional, saturating 38 if dt < 0 { // behind her: no proportional term is valid 39 st = mx 40 if cr > 0 { st = 0 - mx } 41 } 42 // THE INTEGER TAIL, and it is the FLOPPY failure mode arriving through rounding rather than 43 // through a bad gain. The proportional term is mx*sin(error), so once sin(error) falls below 44 // 1/mx it truncates to ZERO and she stops turning while still misaligned -- at the derived 45 // allowance that floor sits near 0.84 degrees, so she would sit permanently just off her own 46 // direction of travel and never arrive. Taking ONE UNIT instead is the smallest turn this 47 // representation can express, so it is the smallest possible repair and needs no constant of 48 // its own. Both guards require a nonzero cross product, so a girl who IS aligned still turns 49 // by nothing at all. 50 // ⚠STATED IMPRECISION: this leaves a one-unit limit cycle about the exact heading, which is 51 // 0.014 degrees and bounded. It is preferred to the alternative, which is a permanent and 52 // UNBOUNDED offset -- a bounded jitter below the angular resolution of the rig beats a 53 // static error you can see. 54 if st == 0 { if cr > 0 { st = 0 - 1 } } 55 if st == 0 { if cr < 0 { st = 1 } } 56 if st > mx { st = mx } 57 if st < 0 - mx { st = 0 - mx } 58 var nh: i64 = hdg + st 59 if nh < 0 { nh = nh + 2*IT_PI } 60 if nh >= 2*IT_PI { nh = nh - 2*IT_PI } 61 return nh 62} 63 64func main() -> i64 { 65 let c: *i64=gv_ctr() 66 gv_head("BEACH-POSE-PAIR-T123" as *u8) 67 var equivalent: i64=1 68 var samples: i64=0 69 var angle: i64=0 70 while angle<2*IT_PI { 71 var dx: i64=0-6 72 while dx<=6 { 73 var dz: i64=0-6 74 while dz<=6 { 75 if wc_hdg_step(angle,dx,dz)!=facing_legacy_step(angle,dx,dz) { equivalent=0 } 76 samples=samples+1;dz=dz+1 77 } 78 dx=dx+1 79 } 80 angle=angle+127 81 } 82 gv_check("movement controller preserves old compiled arithmetic across heading/intention matrix" as *u8,equivalent==1&&samples>0,c) 83 gv_check("positive X intent rotates positive from forward" as *u8,wc_hdg_step(0,4,0)>0,c) 84 gv_check("zero intent preserves heading" as *u8,wc_hdg_step(700,0,0)==700,c) 85 gv_check("stationary social target turns toward player" as *u8,wc_facing_step(0,0,0,400,0,819,205)>0,c) 86 gv_check("stationary outside social radius holds heading" as *u8,wc_facing_step(700,0,0,900,0,819,205)==700,c) 87 gv_check("coincident social position preserves heading" as *u8,wc_facing_step(700,0,0,0,0,819,205)==700,c) 88 gv_check("locomotion wins over conflicting social target" as *u8,wc_facing_step(700,4,0,0-400,0,819,205)==wc_hdg_step(700,4,0),c) 89 gv_check("behind target remains bounded" as *u8,wc_facing_step(0,0,0,0,0-400,819,205)==205,c) 90 let arena: i64=sys_mmap(CRAFT_EXT_TOTAL) as i64 91 let state: *i64=wst(arena) 92 gv_check("explicit facing policy admitted" as *u8,wc_set_facing_policy(arena,819,205)==0&&state[S_FACE_RADIUS]==819&&state[S_FACE_GAIN]==205,c) 93 gv_check("invalid policy leaves admitted state unchanged" as *u8,wc_set_facing_policy(arena,0,205)==0-1&&state[S_FACE_RADIUS]==819&&state[S_FACE_GAIN]==205,c) 94 let hp: *i64=(arena+O_MOBHDG) as *i64 95 hp[0]=700 96 var reads: i64=0 97 var stable: i64=1 98 while reads<144 { 99 if wc_hdg_of(arena,0)!=700 {stable=0} 100 reads=reads+1 101 } 102 gv_check("render heading reads cannot advance native state" as *u8,stable==1&&hp[0]==700,c) 103 sys_munmap(arena as *u8,CRAFT_EXT_TOTAL) 104 let length: *i64=sys_mmap(16) as *i64 105 let plain: *u8=sys_read_file("/tmp/beach-pose-t123.wasm" as *u8,length) 106 let pn: i64=length[0] 107 let twin: *u8=sys_read_file("/tmp/beach-pose-shared-t123.wasm" as *u8,length) 108 let tn: i64=length[0] 109 let plain_wat:*u8=sys_read_file("/tmp/beach-pose-t123.wat" as *u8,length) 110 let pwn:i64=length[0] 111 let shared_wat:*u8=sys_read_file("/tmp/beach-pose-shared-t123.wat" as *u8,length) 112 let swn:i64=length[0] 113 gv_check("actual compiler WAT artifacts read" as *u8,pwn>0&&swn>0,c) 114 if pwn<=0||swn<=0 {return 3} 115 let pr:*u8=sys_mmap(pwn) 116 let sr:*u8=sys_mmap(swn) 117 let rn:i64=wlv_wat(plain_wat,pwn,pr,pwn,0) 118 let sn:i64=wlv_wat(shared_wat,swn,sr,swn,1) 119 gv_check("compiler attached plain and shared layout records decode" as *u8,rn>0&&sn>0,c) 120 gv_check("unterminated WAT evidence refused" as *u8,wlv_wat(plain_wat,pwn-1,pr,pwn,0)==0,c) 121 gv_check("short record destination refused" as *u8,wlv_wat(plain_wat,pwn,pr,WLV_HEADER-1,0)==0,c) 122 gv_check("compiled pair matches existing layout-aware compiler-extension owner" as *u8,pn>0&&tn>0&&rn>0&&sn>0&&gpl_pair(plain,pn,twin,tn,pr,rn,sr,sn)==1,c) 123 if rn>0&&sn>0 { 124 gv_check("truncated layout record refused" as *u8,gpl_pair(plain,pn,twin,tn,pr,rn-1,sr,sn)==0,c) 125 gv_check("plain record cannot stand in for shared reservation" as *u8,gpl_pair(plain,pn,twin,tn,pr,rn,pr,rn)==0,c) 126 let before:u8=sr[40] 127 sr[40]=((before as i64)^1) as u8 128 gv_check("altered shared initializer reservation refused" as *u8,gpl_pair(plain,pn,twin,tn,pr,rn,sr,sn)==0,c) 129 sr[40]=before 130 gv_check("restored original records requalify exact pair" as *u8,gpl_pair(plain,pn,twin,tn,pr,rn,sr,sn)==1,c) 131 let wh:*u8=sys_mmap(65) 132 gpa_sha(plain_wat,pwn,wh);fsx_puts("plain_wat_sha256=");fsx_puts(wh);fsx_puts(" bytes=");fsx_putn(pwn);fsx_puts("\n") 133 gpa_sha(shared_wat,swn,wh);fsx_puts("shared_wat_sha256=");fsx_puts(wh);fsx_puts(" bytes=");fsx_putn(swn);fsx_puts("\n") 134 gpa_sha(pr,rn,wh);fsx_puts("plain_layout_sha256=");fsx_puts(wh);fsx_puts(" bytes=");fsx_putn(rn);fsx_puts("\n") 135 gpa_sha(sr,sn,wh);fsx_puts("shared_layout_sha256=");fsx_puts(wh);fsx_puts(" bytes=");fsx_putn(sn);fsx_puts("\n") 136 } 137 if pn>0&&tn>0 { 138 let ph: *u8=sys_mmap(65) 139 let th: *u8=sys_mmap(65) 140 gpa_sha(plain,pn,ph);gpa_sha(twin,tn,th) 141 fsx_puts("plain_sha256=");fsx_puts(ph);fsx_puts(" bytes=");fsx_putn(pn);fsx_puts("\n") 142 fsx_puts("shared_sha256=");fsx_puts(th);fsx_puts(" bytes=");fsx_putn(tn);fsx_puts("\n") 143 } 144 return gv_verdict("BEACH-POSE-PAIR-T123" as *u8,c,"Native control qualification; served motion acceptance pending" as *u8) 145}