nmarshall commited on
Commit
d7fa9fd
·
1 Parent(s): fdff40a

qvm: pose pitch and lateral scratch

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -664,3 +664,6 @@ Research progress: RE-661 [report](research/QVM_VECTOR_ANGLES.md); remaining nat
664
 
665
 
666
  Research progress: RE-662 [report](research/QVM_POSE_MOTION_YAW.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
664
 
665
 
666
  Research progress: RE-662 [report](research/QVM_POSE_MOTION_YAW.md); remaining native/content/runtime/platform scope stays open.
667
+
668
+
669
+ Research progress: RE-663 [report](research/QVM_POSE_LEAN.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -1010,3 +1010,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
1010
 
1011
 
1012
  **RE-662 — Animation-dispatched movement yaw and speed scaling:** 32254 dispatches forward/reverse/default yaw branches, clamps integer horizontal speed to200 and yaw delta to±60, and preserves an integer reciprocal scratch calculation. [Evidence](research/QVM_POSE_MOTION_YAW.md).
 
 
 
 
1010
 
1011
 
1012
  **RE-662 — Animation-dispatched movement yaw and speed scaling:** 32254 dispatches forward/reverse/default yaw branches, clamps integer horizontal speed to200 and yaw delta to±60, and preserves an integer reciprocal scratch calculation. [Evidence](research/QVM_POSE_MOTION_YAW.md).
1013
+
1014
+
1015
+ **RE-663 — Pose pitch publication and lateral scratch arithmetic:** 32254 publishes animation-biased pitch, normalizes full velocity with a floating reciprocal and computes an unconsumed lateral scratch scalar. [Evidence](research/QVM_POSE_LEAN.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -987,3 +987,6 @@ Research progress: RE-661 [report](research/QVM_VECTOR_ANGLES.md); remaining nat
987
 
988
 
989
  Research progress: RE-662 [report](research/QVM_POSE_MOTION_YAW.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
987
 
988
 
989
  Research progress: RE-662 [report](research/QVM_POSE_MOTION_YAW.md); remaining native/content/runtime/platform scope stays open.
990
+
991
+
992
+ Research progress: RE-663 [report](research/QVM_POSE_LEAN.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -972,3 +972,8 @@ One direct append caller156173 and three direct reset callers174399/203011/21963
972
  ## 2026-10-20 — RE-662 Animation-dispatched movement yaw and speed scaling (separate task commit)
973
 
974
  32254 dispatches forward/reverse/default yaw branches, clamps integer horizontal speed to200 and yaw delta to±60, and preserves an integer reciprocal scratch calculation. 144 fixtures independently check dispatch, integer/sqrt boundaries, signed deltas, capped speed, actual62944/63746 composition and signed zero scratch vectors. Full suite: 1113 tests pass. Report regenerates byte-identically (588314 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
972
  ## 2026-10-20 — RE-662 Animation-dispatched movement yaw and speed scaling (separate task commit)
973
 
974
  32254 dispatches forward/reverse/default yaw branches, clamps integer horizontal speed to200 and yaw delta to±60, and preserves an integer reciprocal scratch calculation. 144 fixtures independently check dispatch, integer/sqrt boundaries, signed deltas, capped speed, actual62944/63746 composition and signed zero scratch vectors. Full suite: 1113 tests pass. Report regenerates byte-identically (588314 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
975
+
976
+
977
+ ## 2026-10-20 — RE-663 Pose pitch publication and lateral scratch arithmetic (separate task commit)
978
+
979
+ 32254 publishes animation-biased pitch, normalizes full velocity with a floating reciprocal and computes an unconsumed lateral scratch scalar. 96 fixtures independently check pitch gating/bias, full3D float32 normalization, scaled length, basis/dot arithmetic and zero-velocity call suppression. Full suite: 1117 tests pass. Report regenerates byte-identically (300961 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -1030,3 +1030,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1030
 
1031
 
1032
  - [x] RE-662 Animation-dispatched movement yaw and speed scaling ([report](research/QVM_POSE_MOTION_YAW.md)).
 
 
 
 
1030
 
1031
 
1032
  - [x] RE-662 Animation-dispatched movement yaw and speed scaling ([report](research/QVM_POSE_MOTION_YAW.md)).
1033
+
1034
+
1035
+ - [x] RE-663 Pose pitch publication and lateral scratch arithmetic ([report](research/QVM_POSE_LEAN.md)).
docs/research/QVM_POSE_LEAN.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Pose pitch publication and lateral scratch arithmetic
2
+
3
+ RE-663. Reproduce with `python3 scripts/analyze_qvm_pose_lean.py`; check with `python3 scripts/test_qvm_pose_lean.py`. The [machine report](qvm-pose-lean.json) retains source identity and bounded fixtures.
4
+
5
+ Actual32797–33167 uses half-pitch only when flag96 is active, subtracts360 once above180, adds15 for IDs20/21 or5 otherwise, and publishes through argument40. Velocity is freshly copied and normalized with floating1/length, unlike the earlier integer reciprocal scratch. Nonzero velocity scales length by0.1, builds a basis from local60/64/68 and computes a lateral dot-product scalar at local168. The remaining32254 instructions contain no LOAD of that scalar, so it is documented as an unconsumed calculation rather than a proven visible lean effect. Zero velocity skips basis/native trig calls. Finite sqrt/trig models and original legal-input/library limitations remain explicit.
6
+
7
+ No original executable/full QVM/native collision/physics/rendering executes. Native responses and legal input domains are supplied or unverified where stated; full runtime/macOS/Linux Rust/Bevy/Solari gameplay remains open.
docs/research/README.md CHANGED
@@ -588,3 +588,6 @@ The extension collector adds five focused tests for native tail calls, command-r
588
 
589
 
590
  [RE-662: Animation-dispatched movement yaw and speed scaling](QVM_POSE_MOTION_YAW.md). Reproduce with `python3 scripts/analyze_qvm_pose_motion_yaw.py`; check with `python3 scripts/test_qvm_pose_motion_yaw.py`.
 
 
 
 
588
 
589
 
590
  [RE-662: Animation-dispatched movement yaw and speed scaling](QVM_POSE_MOTION_YAW.md). Reproduce with `python3 scripts/analyze_qvm_pose_motion_yaw.py`; check with `python3 scripts/test_qvm_pose_motion_yaw.py`.
591
+
592
+
593
+ [RE-663: Pose pitch publication and lateral scratch arithmetic](QVM_POSE_LEAN.md). Reproduce with `python3 scripts/analyze_qvm_pose_lean.py`; check with `python3 scripts/test_qvm_pose_lean.py`.
docs/research/qvm-pose-lean.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_pose_lean.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Pose pitch publication, full velocity normalization and lateral scratch scalar."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source,execute,constants
6
+ from qvm_shot_math_support import TRIG
7
+ from analyze_qvm_pose_prefix import fixture,LOCAL,VELOCITY
8
+ from analyze_qvm_pose_controllers import controllers
9
+ from analyze_qvm_pose_motion_yaw import motion
10
+ from analyze_qvm_acceleration import word
11
+ from analyze_qvm_slide_prefix import vec
12
+ from analyze_qvm import write_json
13
+
14
+ def lean(ins,m):
15
+ m=dict(m);before={'animation':m[LOCAL+88],'pitch':m[LOCAL+48]&0xffffffff,'active':m[LOCAL+96],'velocity':vec(m,m[LOCAL+248]),'basis_angles':vec(m,LOCAL+60)}
16
+ m,_,e=execute(ins,32797,33168,m,(0,0,0),LOCAL,TRIG)
17
+ nonzero=any(v&0x7fffffff for v in before['velocity'])
18
+ return m,{'initial':before,'published_pitch':m[m[LOCAL+276]]&0xffffffff,'body_pitch':m[LOCAL+36]&0xffffffff,'velocity_unit':vec(m,LOCAL+72),'scaled_length':m[LOCAL+84]&0xffffffff,'lateral_scalar':m[LOCAL+168]&0xffffffff if nonzero else None,'execution':e}
19
+
20
+ def main():
21
+ q,raw,h,ins=source();constants_map=constants(raw,h,list(range(20536+22*4,20536+41*4,4))+[21348,21352,21356]);rows=[]
22
+ for first,second,pitch,velocity in itertools.product([0,20,21,41],[0,22],[0,30,400,-400],[(0,0,0),(3,4,12),(-.5,1,0)]):
23
+ m,a=fixture(first,second,(pitch,45,0));m.update(constants_map)
24
+ for j,v in enumerate(velocity):m[VELOCITY+4*j]=word(v)
25
+ m,_=controllers(ins,m,a);m,_=motion(ins,m);rows.append(lean(ins,m)[1])
26
+ write_json(Path('docs/research/qvm-pose-lean.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual32797–33167 after actual controllers/motion. Explicit finite sqrt/trig responses. Lateral scalar local168 is scratch and has no subsequent LOAD in32254; no asserted physical lean effect or original native parity.'})
27
+ if __name__=='__main__':main()
scripts/test_qvm_pose_lean.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest,math
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,n,f
4
+ from test_qvm_server_fire_basis import vectors
5
+
6
+ def expected(p):
7
+ a=p['initial'];pitch=n(a['pitch']) if a['active'] else 0
8
+ if a['active'] and pitch>180:pitch=f(pitch-360)
9
+ pitch=f(pitch+(15 if a['animation'] in [20,21] else 5));v=list(map(n,a['velocity']));length=f(math.sqrt(f(f(f(v[0]*v[0])+f(v[1]*v[1]))+f(v[2]*v[2]))));unit=[f(x*f(1/length)) for x in v] if length else v
10
+ if not length:return word(pitch),list(map(word,unit)),word(length),None
11
+ scaled=f(length*n(1036831949));right=vectors(a['basis_angles'])[1];opposite=[f(0-n(x)) for x in right];dot=f(f(f(unit[0]*opposite[0])+f(unit[1]*opposite[1]))+f(unit[2]*opposite[2]));scalar=f(scaled*dot)
12
+ return word(pitch),list(map(word,unit)),word(scaled),word(scalar)
13
+ class PoseLeanTests(unittest.TestCase):
14
+ @classmethod
15
+ def setUpClass(cls):cls.rows=json.loads(Path('docs/research/qvm-pose-lean.json').read_text())['probes']
16
+ def test_independent_pitch_normalization_and_lateral_scalar(self):
17
+ self.assertEqual(len(self.rows),96)
18
+ for p in self.rows:self.assertEqual((p['published_pitch'],p['velocity_unit'],p['scaled_length'],p['lateral_scalar']),expected(p));self.assertEqual(p['body_pitch'],p['published_pitch'])
19
+ def test_zero_velocity_skips_basis_calls(self):
20
+ for p in self.rows:self.assertEqual([c['target'] for c in p['execution']['calls']],[-107]+([-104,-105]*3 if p['lateral_scalar'] is not None else []))
21
+ def test_pitch_special_ids_and_inactive_cases_present(self):
22
+ self.assertEqual({p['initial']['animation'] for p in self.rows},{0,20,21,41});self.assertEqual({p['initial']['active'] for p in self.rows},{0,1})
23
+ def test_lateral_scratch_has_no_later_consumer(self):
24
+ from qvm_research_support import source
25
+ ins=source()[3]
26
+ self.assertFalse(any(a['opcode']=='LOCAL' and a['operand']==168 and b['opcode']=='LOAD4' for a,b in zip(ins[33168:33389],ins[33169:33390])))
27
+ if __name__=='__main__':unittest.main()