qvm: complete model hit helper
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +3 -0
- docs/PROVISIONAL_TODO.md +3 -0
- docs/RESEARCH_LEDGER.md +5 -0
- docs/REVERSE_ENGINEERING_TODO.md +3 -0
- docs/research/QVM_COMPLETE_MODEL_HIT.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-complete-model-hit.json +0 -0
- scripts/analyze_qvm_complete_model_hit.py +56 -0
- scripts/analyze_qvm_geometric_hierarchy.py +2 -2
- scripts/test_qvm_complete_model_hit.py +23 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -733,3 +733,6 @@ Research progress: RE-686 [report](research/QVM_COMPLETE_LEAF.md); remaining nat
|
|
| 733 |
|
| 734 |
|
| 735 |
Research progress: RE-687 [report](research/QVM_GEOMETRIC_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 733 |
|
| 734 |
|
| 735 |
Research progress: RE-687 [report](research/QVM_GEOMETRIC_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
|
| 736 |
+
|
| 737 |
+
|
| 738 |
+
Research progress: RE-688 [report](research/QVM_COMPLETE_MODEL_HIT.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -1079,3 +1079,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 1079 |
|
| 1080 |
|
| 1081 |
**RE-687 — Recursive model traversal with actual leaf geometry:** 25341 now composes actual22009 and23092 through recursive hierarchies, producing hit records from packed geometry rather than supplied leaf replies. [Evidence](research/QVM_GEOMETRIC_HIERARCHY.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1079 |
|
| 1080 |
|
| 1081 |
**RE-687 — Recursive model traversal with actual leaf geometry:** 25341 now composes actual22009 and23092 through recursive hierarchies, producing hit records from packed geometry rather than supplied leaf replies. [Evidence](research/QVM_GEOMETRIC_HIERARCHY.md).
|
| 1082 |
+
|
| 1083 |
+
|
| 1084 |
+
**RE-688 — Complete model-hit helper through geometry and publication:** Complete144766 now executes actual pose/hierarchy/leaf geometry/classification/sorting and returns geometric hit0/1 with exact trace publication. [Evidence](research/QVM_COMPLETE_MODEL_HIT.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1062,3 +1062,6 @@ Research progress: RE-686 [report](research/QVM_COMPLETE_LEAF.md); remaining nat
|
|
| 1062 |
|
| 1063 |
|
| 1064 |
Research progress: RE-687 [report](research/QVM_GEOMETRIC_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 1062 |
|
| 1063 |
|
| 1064 |
Research progress: RE-687 [report](research/QVM_GEOMETRIC_HIERARCHY.md); remaining native/content/runtime/platform scope stays open.
|
| 1065 |
+
|
| 1066 |
+
|
| 1067 |
+
Research progress: RE-688 [report](research/QVM_COMPLETE_MODEL_HIT.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -1087,3 +1087,8 @@ Complete23092 now produces actual geometry-derived context records through packe
|
|
| 1087 |
## 2026-10-21 — RE-687 Recursive model traversal with actual leaf geometry (separate task commit)
|
| 1088 |
|
| 1089 |
25341 now composes actual22009 and23092 through recursive hierarchies, producing hit records from packed geometry rather than supplied leaf replies. 18 postorder compositions independently check every leaf context, ancestry matrix, carried record count, hit/miss outcome and caller return. Full suite: 1206 tests pass. Report regenerates byte-identically (423592 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1087 |
## 2026-10-21 — RE-687 Recursive model traversal with actual leaf geometry (separate task commit)
|
| 1088 |
|
| 1089 |
25341 now composes actual22009 and23092 through recursive hierarchies, producing hit records from packed geometry rather than supplied leaf replies. 18 postorder compositions independently check every leaf context, ancestry matrix, carried record count, hit/miss outcome and caller return. Full suite: 1206 tests pass. Report regenerates byte-identically (423592 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 1090 |
+
|
| 1091 |
+
|
| 1092 |
+
## 2026-10-21 — RE-688 Complete model-hit helper through geometry and publication (separate task commit)
|
| 1093 |
+
|
| 1094 |
+
Complete144766 now executes actual pose/hierarchy/leaf geometry/classification/sorting and returns geometric hit0/1 with exact trace publication. 16 full model compositions independently check pose, every leaf context, actual hit/miss, recognized categories, source child order and final trace words. Full suite: 1210 tests pass. Report regenerates byte-identically (575367 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
|
@@ -1105,3 +1105,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1105 |
|
| 1106 |
|
| 1107 |
- [x] RE-687 Recursive model traversal with actual leaf geometry ([report](research/QVM_GEOMETRIC_HIERARCHY.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1105 |
|
| 1106 |
|
| 1107 |
- [x] RE-687 Recursive model traversal with actual leaf geometry ([report](research/QVM_GEOMETRIC_HIERARCHY.md)).
|
| 1108 |
+
|
| 1109 |
+
|
| 1110 |
+
- [x] RE-688 Complete model-hit helper through geometry and publication ([report](research/QVM_COMPLETE_MODEL_HIT.md)).
|
docs/research/QVM_COMPLETE_MODEL_HIT.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Complete model-hit helper through geometry and publication
|
| 2 |
+
|
| 3 |
+
RE-688. Reproduce with `python3 scripts/analyze_qvm_complete_model_hit.py`; check with `python3 scripts/test_qvm_complete_model_hit.py`. The [machine report](qvm-complete-model-hit.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Complete144767–146620 dispatches actual32254,25341,23092 and25835 over explicit packed models. Native math and bounded zero fill remain models. The new root-only fixtures use actual target/client pointers, frame0/22 records and yaw-dependent bases; hit results arise from source intersection rather than supplied replies. Trace point/normal/target ID publication matches independent geometry-derived contexts, and no-hit traces retain their initial words. Separate input and hit-output buffers avoid accidental fixture aliasing. Original asset identities/live bounds/native engine parity remain open.
|
| 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
|
@@ -663,3 +663,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 663 |
|
| 664 |
|
| 665 |
[RE-687: Recursive model traversal with actual leaf geometry](QVM_GEOMETRIC_HIERARCHY.md). Reproduce with `python3 scripts/analyze_qvm_geometric_hierarchy.py`; check with `python3 scripts/test_qvm_geometric_hierarchy.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 663 |
|
| 664 |
|
| 665 |
[RE-687: Recursive model traversal with actual leaf geometry](QVM_GEOMETRIC_HIERARCHY.md). Reproduce with `python3 scripts/analyze_qvm_geometric_hierarchy.py`; check with `python3 scripts/test_qvm_geometric_hierarchy.py`.
|
| 666 |
+
|
| 667 |
+
|
| 668 |
+
[RE-688: Complete model-hit helper through geometry and publication](QVM_COMPLETE_MODEL_HIT.md). Reproduce with `python3 scripts/analyze_qvm_complete_model_hit.py`; check with `python3 scripts/test_qvm_complete_model_hit.py`.
|
docs/research/qvm-complete-model-hit.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_complete_model_hit.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Complete144766 with actual pose, hierarchy/leaf geometry, sort/publication."""
|
| 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_complete_pose import pose
|
| 8 |
+
from analyze_qvm_model_ray_prefix import LOCAL
|
| 9 |
+
from analyze_qvm_model_transforms import BUFFERS,TABLES
|
| 10 |
+
from analyze_qvm_geometric_hierarchy import attach,geometric_walk
|
| 11 |
+
from analyze_qvm_complete_leaf import words
|
| 12 |
+
from analyze_qvm_surface_category import support
|
| 13 |
+
from analyze_qvm_hit_publication import SORT
|
| 14 |
+
from analyze_qvm_shot_trace_request import fixture as trace_fixture,TRACE,END,HIT
|
| 15 |
+
from analyze_qvm_entity_init import POOL,STRIDE
|
| 16 |
+
from analyze_qvm_acceleration import word
|
| 17 |
+
from analyze_qvm_slide_prefix import vec
|
| 18 |
+
from analyze_qvm import write_json
|
| 19 |
+
|
| 20 |
+
START=END+0x3000
|
| 21 |
+
|
| 22 |
+
def complete(ins,m,bs,args,names):
|
| 23 |
+
m=dict(m);before=words(m,args[12],14);poses=[];hierarchies=[];sorts=[]
|
| 24 |
+
for o,v in args.items():m[LOCAL+312+o]=v
|
| 25 |
+
def posed(i,m,a,c):m,r=pose(i,m,a);poses.append(r);return m,c,0,{'pose_index':len(poses)-1}
|
| 26 |
+
def zero(i,m,a,c):
|
| 27 |
+
assert a[8] in BUFFERS and a[12]==0 and a[16]==88
|
| 28 |
+
for o in range(0,88,4):m[a[8]+o]=0
|
| 29 |
+
return m,c,0,{'bounded_zero_fill':a}
|
| 30 |
+
def geometry(i,m,a,c):m,r=geometric_walk(i,m,bs,a,names);hierarchies.append(r);return m,c,0,{'hierarchy_index':len(hierarchies)-1}
|
| 31 |
+
def sort(i,m,a,c):
|
| 32 |
+
pointer=a[8];initial=words(m,pointer);m[SORT+56]=pointer;m,_,e=execute(i,25836,26036,m,c,SORT);r={'before':initial,'after':words(m,pointer),'execution':e};sorts.append(r);return m,c,0,{'sort_index':len(sorts)-1}
|
| 33 |
+
m,_,e=execute(ins,144767,146621,m,(0,0,0),LOCAL,{**TRIG,32254:posed,-101:zero,25341:geometry,25835:sort})
|
| 34 |
+
return m,{'arguments':args,'before_trace':before,'after_trace':words(m,args[12],14),'poses':poses,'hierarchies':hierarchies,'sorts':sorts,'context':words(m,args[24]),'execution':e}
|
| 35 |
+
|
| 36 |
+
def prepare(raw,h,animation=0,yaw=0,hit=True,name='h_head',m=None,shooter=None):
|
| 37 |
+
if m is None:m,a=trace_fixture(raw,h);shooter=a[8]
|
| 38 |
+
else:m=dict(m)
|
| 39 |
+
s,bs=support(raw,h);m.update(s);m.update(constants(raw,h,list(range(20624,20700,4))+[21348,21352,21356]));target=POOL+65*STRIDE;client=m[target+520];m[TRACE+52]=65;m[target]=65;m[client+700]=0
|
| 40 |
+
for o,v in [(6196,0),(6204,animation),(6212,word(.5)),(6248,0),(6256,animation),(6264,word(.5))]:m[client+o]=v
|
| 41 |
+
for o in [4380,4384,4388,4392]:m[client+o]=0
|
| 42 |
+
source_client=m[shooter+520];m[source_client]=200;m[source_client+6176]=216
|
| 43 |
+
for p,v in [(target+24,(0,0,0)),(target+36,(0,0,0)),(target+60,(0,yaw,0)),(END,(.2,.5,0) if hit else (20,20,0)),(START,(.2,.5,1) if hit else (20,20,1))]:
|
| 44 |
+
for j,x in enumerate(v):m[p+4*j]=word(x)
|
| 45 |
+
for table,p in zip(TABLES,BUFFERS):
|
| 46 |
+
m[table]=p;m[p+88]=p+1024;m[p+92]=0;m[p+96]=0;m[p+1024+80]=0
|
| 47 |
+
attach(m,bs,BUFFERS[0],0x78f00000,name,frame_count=23)
|
| 48 |
+
for o in range(0,308,4):m[HIT+o]=0
|
| 49 |
+
return m,bs,{8:shooter,12:TRACE,16:START,20:END,24:HIT},{BUFFERS[0]:name}
|
| 50 |
+
|
| 51 |
+
def main():
|
| 52 |
+
q,raw,h,ins=source();rows=[]
|
| 53 |
+
for animation,yaw,hit,name in itertools.product([0,22],[0,45],[False,True],['h_head','u_torso']):
|
| 54 |
+
m,bs,a,names=prepare(raw,h,animation,yaw,hit,name);m,r=complete(ins,m,bs,a,names);r['fixture']={'animation':animation,'yaw':yaw,'hit':hit,'name':name};rows.append(r)
|
| 55 |
+
write_json(Path('docs/research/qvm-complete-model-hit.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Complete144766 with actual32254/25341/22009/23092/25835 on explicit model tables and packed surface geometry. Here root has no children; broader hierarchy separate. Native math/zero fill modeled, no original assets/runtime/native world parity.'})
|
| 56 |
+
if __name__=='__main__':main()
|
scripts/analyze_qvm_geometric_hierarchy.py
CHANGED
|
@@ -12,10 +12,10 @@ from analyze_qvm import write_json
|
|
| 12 |
VERTICES=[[0,0,0],[256,0,0],[0,256,0]]
|
| 13 |
NAMES=['h_head','u_torso','l_rfoot','g_vest']
|
| 14 |
|
| 15 |
-
def attach(m,bs,node,part,name,vertices=VERTICES):
|
| 16 |
model=m[node+88];m[model+84]=1;m[model+100]=part-model;m.update({part+80:3,part+84:1,part+88:128,part+100:512,part+104:1024});put_text(m,bs,part+4,name.encode())
|
| 17 |
for j in range(3):m[part+128+4*j]=j
|
| 18 |
-
for frame in range(
|
| 19 |
for j,v in enumerate(vertices):
|
| 20 |
address=part+512+(frame*3+j)*8;data=b''.join(int(x).to_bytes(2,'little',signed=True) for x in v)+b'\0\0'
|
| 21 |
for k,b in enumerate(data):bs[address+k]=b
|
|
|
|
| 12 |
VERTICES=[[0,0,0],[256,0,0],[0,256,0]]
|
| 13 |
NAMES=['h_head','u_torso','l_rfoot','g_vest']
|
| 14 |
|
| 15 |
+
def attach(m,bs,node,part,name,vertices=VERTICES,frame_count=2):
|
| 16 |
model=m[node+88];m[model+84]=1;m[model+100]=part-model;m.update({part+80:3,part+84:1,part+88:128,part+100:512,part+104:1024});put_text(m,bs,part+4,name.encode())
|
| 17 |
for j in range(3):m[part+128+4*j]=j
|
| 18 |
+
for frame in range(frame_count):
|
| 19 |
for j,v in enumerate(vertices):
|
| 20 |
address=part+512+(frame*3+j)*8;data=b''.join(int(x).to_bytes(2,'little',signed=True) for x in v)+b'\0\0'
|
| 21 |
for k,b in enumerate(data):bs[address+k]=b
|
scripts/test_qvm_complete_model_hit.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_complete_leaf import expected as leaf
|
| 4 |
+
from test_qvm_complete_pose import expected as pose
|
| 5 |
+
class CompleteModelHitTests(unittest.TestCase):
|
| 6 |
+
@classmethod
|
| 7 |
+
def setUpClass(cls):cls.rows=json.loads(Path('docs/research/qvm-complete-model-hit.json').read_text())['probes']
|
| 8 |
+
def test_independent_pose_and_complete_leaf_geometry(self):
|
| 9 |
+
self.assertEqual(len(self.rows),16)
|
| 10 |
+
for p in self.rows:
|
| 11 |
+
state,angles,flag=pose(p['poses'][0]);self.assertEqual(p['poses'][0]['final_state'],state);self.assertEqual(p['poses'][0]['output_legs_body_head'],angles)
|
| 12 |
+
for r in p['hierarchies'][0]['leaf_reports']:self.assertEqual(r['effect']['after'],leaf(r['effect']))
|
| 13 |
+
def test_exact_numeric_return_and_trace_publication(self):
|
| 14 |
+
for p in self.rows:
|
| 15 |
+
hit=bool(p['context'][16]);expected=p['before_trace'][:]
|
| 16 |
+
if hit:expected[3:6]=p['context'][3:6];expected[6:9]=p['context'][9:12];expected[13]=65
|
| 17 |
+
self.assertEqual(p['after_trace'],expected);self.assertEqual(p['execution']['return'],int(hit));self.assertEqual(hit,p['fixture']['hit'])
|
| 18 |
+
def test_actual_source_callee_order(self):
|
| 19 |
+
for p in self.rows:self.assertEqual([c['target'] for c in p['execution']['calls']],[-107,32254]+[-101]*4+[-104,-105]*9+[25341,25835])
|
| 20 |
+
def test_hit_records_come_from_geometry_and_recognized_names(self):
|
| 21 |
+
for p in self.rows:
|
| 22 |
+
if p['fixture']['hit']:self.assertEqual(p['context'][17],1 if p['fixture']['name']=='h_head' else 3);self.assertEqual(p['sorts'][0]['before'],p['sorts'][0]['after'])
|
| 23 |
+
if __name__=='__main__':unittest.main()
|