nmarshall commited on
Commit
6e5a135
·
1 Parent(s): 03d6b2b

qvm: contact event value and direction

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -817,3 +817,6 @@ Research progress: RE-716 [report](research/QVM_CONTACT_ANNOUNCEMENT.md); remain
817
 
818
 
819
  Research progress: RE-717 [report](research/QVM_CONTACT_EVENT_HEADER.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
817
 
818
 
819
  Research progress: RE-717 [report](research/QVM_CONTACT_EVENT_HEADER.md); remaining native/content/runtime/platform scope stays open.
820
+
821
+
822
+ Research progress: RE-718 [report](research/QVM_CONTACT_EVENT_VALUE.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -1163,3 +1163,6 @@ RE-703–712 batch complete: [damage factor and contact dispatch](research/QVM_D
1163
 
1164
 
1165
  **RE-717 — Contact event header and health prediction:** Contact allocates event62 through actual277695, encodes the normal through60317, publishes IDs/location/part and predicts lethality using float32 health−scalar≤0 without applying damage. [Evidence](research/QVM_CONTACT_EVENT_HEADER.md).
 
 
 
 
1163
 
1164
 
1165
  **RE-717 — Contact event header and health prediction:** Contact allocates event62 through actual277695, encodes the normal through60317, publishes IDs/location/part and predicts lethality using float32 health−scalar≤0 without applying damage. [Evidence](research/QVM_CONTACT_EVENT_HEADER.md).
1166
+
1167
+
1168
+ **RE-718 — Contact event scalar and direction payload:** Event204 truncates ordinary scalar or weapon4 accumulator×100 with upper cap100 only; exact trace point replaces the snapped trajectory base, and event36 stores normalized attacker-minus-target separation. [Evidence](research/QVM_CONTACT_EVENT_VALUE.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1152,3 +1152,6 @@ Research progress: RE-716 [report](research/QVM_CONTACT_ANNOUNCEMENT.md); remain
1152
 
1153
 
1154
  Research progress: RE-717 [report](research/QVM_CONTACT_EVENT_HEADER.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
1152
 
1153
 
1154
  Research progress: RE-717 [report](research/QVM_CONTACT_EVENT_HEADER.md); remaining native/content/runtime/platform scope stays open.
1155
+
1156
+
1157
+ Research progress: RE-718 [report](research/QVM_CONTACT_EVENT_VALUE.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -1225,3 +1225,8 @@ Events require nonzero caller flag and scalar; announcement7259 additionally req
1225
  ## 2026-10-21 — RE-717 Contact event header and health prediction (separate task commit)
1226
 
1227
  Contact allocates event62 through actual277695, encodes the normal through60317, publishes IDs/location/part and predicts lethality using float32 health−scalar≤0 without applying damage. 72 health/scalar/normal/part fixtures verify all220 event words, actual child order and the earlier native-link snapshot. Full suite: 1316 tests pass. Report regenerates byte-identically (1919852 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
1225
  ## 2026-10-21 — RE-717 Contact event header and health prediction (separate task commit)
1226
 
1227
  Contact allocates event62 through actual277695, encodes the normal through60317, publishes IDs/location/part and predicts lethality using float32 health−scalar≤0 without applying damage. 72 health/scalar/normal/part fixtures verify all220 event words, actual child order and the earlier native-link snapshot. Full suite: 1316 tests pass. Report regenerates byte-identically (1919852 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
1228
+
1229
+
1230
+ ## 2026-10-21 — RE-718 Contact event scalar and direction payload (separate task commit)
1231
+
1232
+ Event204 truncates ordinary scalar or weapon4 accumulator×100 with upper cap100 only; exact trace point replaces the snapped trajectory base, and event36 stores normalized attacker-minus-target separation. 54 constructor-through-direction probes verify all220 event words, signed truncation, upper-only cap, zero vectors and exact versus snapped coordinates. Full suite: 1320 tests pass. Report regenerates byte-identically (1468138 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
@@ -1195,3 +1195,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1195
 
1196
 
1197
  - [x] RE-717 Contact event header and health prediction ([report](research/QVM_CONTACT_EVENT_HEADER.md)).
 
 
 
 
1195
 
1196
 
1197
  - [x] RE-717 Contact event header and health prediction ([report](research/QVM_CONTACT_EVENT_HEADER.md)).
1198
+
1199
+
1200
+ - [x] RE-718 Contact event scalar and direction payload ([report](research/QVM_CONTACT_EVENT_VALUE.md)).
docs/research/QVM_CONTACT_EVENT_VALUE.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Contact event scalar and direction payload
2
+
3
+ RE-718. Reproduce with `python3 scripts/analyze_qvm_contact_event_value.py`; check with `python3 scripts/test_qvm_contact_event_value.py`. The [machine report](qvm-contact-event-value.json) retains source identity and bounded fixtures.
4
+
5
+ Actual292917–293221 composes the event header with subsequent value/direction writes. Ordinary event204 is truncating float-to-integer scalar; weapon4 uses the extra accumulator×100 and caps only values above100, preserving explicit negative fixtures. Weapon ID goes to196. Trace point bytes overwrite event24 without truncation, while constructor origin488 remains snapped. Event36/40/44 is attacker entity24 minus target entity24, normalized using source-order float32 squared sums, modeled native sqrt, reciprocal and products; zero separation stays zero. The independent oracle checks the entire record. Allocation/native link and native sqrt parity remain explicit boundaries. No feedback or health execution occurs.
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
@@ -753,3 +753,6 @@ The extension collector adds five focused tests for native tail calls, command-r
753
 
754
 
755
  [RE-717: Contact event header and health prediction](QVM_CONTACT_EVENT_HEADER.md). Reproduce with `python3 scripts/analyze_qvm_contact_event_header.py`; check with `python3 scripts/test_qvm_contact_event_header.py`.
 
 
 
 
753
 
754
 
755
  [RE-717: Contact event header and health prediction](QVM_CONTACT_EVENT_HEADER.md). Reproduce with `python3 scripts/analyze_qvm_contact_event_header.py`; check with `python3 scripts/test_qvm_contact_event_header.py`.
756
+
757
+
758
+ [RE-718: Contact event scalar and direction payload](QVM_CONTACT_EVENT_VALUE.md). Reproduce with `python3 scripts/analyze_qvm_contact_event_value.py`; check with `python3 scripts/test_qvm_contact_event_value.py`.
docs/research/qvm-contact-event-value.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_contact_event_value.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Actual contact event value, exact point copy and normalized separation vector."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source
6
+ from qvm_contact_support import seed,run
7
+ from analyze_qvm import write_json
8
+
9
+ def main():
10
+ q,raw,h,ins=source();rows=[]
11
+ for w,scalar,extra,origin in itertools.product([3,4,27],[-2.9,0.9,35.75],[-0.5,0.999,1.5],[(0,0,0),(3,4,0)]):
12
+ a=dict(weapon=w,scalar=scalar,extra=extra,attacker_origin=origin);_,p=run(ins,seed(raw,h,**a),292917,293222,include_event=True);p['input']=a;rows.append(p)
13
+ write_json(Path('docs/research/qvm-contact-event-value.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual292917..293221, constructor and codec. Sqrt is modeled float32 native math; allocator/link explicit. No feedback/health or post-direction event vector suffix.'})
14
+ if __name__=='__main__':main()
scripts/test_qvm_contact_event_value.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,math,unittest
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,n,f
4
+ from test_qvm_temp_event import event_record
5
+ from test_qvm_direction_codec import best
6
+
7
+ def normalized(a,b):
8
+ v=[f(f(x)-f(y)) for x,y in zip(a,b)];length=f(math.sqrt(f(f(f(v[0]*v[0])+f(v[1]*v[1]))+f(v[2]*v[2]))))
9
+ return list(map(word,v if length==0 else [f(x*f(1./length)) for x in v]))
10
+ class ContactEventValueTests(unittest.TestCase):
11
+ @classmethod
12
+ def setUpClass(cls):cls.ps=json.loads(Path('docs/research/qvm-contact-event-value.json').read_text())['probes'];cls.table=json.loads(Path('docs/research/qvm-direction-codec.json').read_text())['table']
13
+ def test_full_record_independent_event_and_suffix_oracle(self):
14
+ for p in self.ps:
15
+ a=p['input'];e=p['effects']['events'][0];r=event_record(e);encoded=math.trunc(f(a['scalar'])) if a['weapon']!=4 else min(100,math.trunc(f(f(a['extra'])*100)))
16
+ r.update({'424':32,'184':best([0,0,word(1)],self.table),'140':7,'144':65,'88':3,'84':2,'200':int(f(100-f(a['scalar']))<=0),'204':encoded&0xffffffff,'196':a['weapon']})
17
+ for j,v in enumerate(e['input_origin']):r[str(24+4*j)]=v
18
+ for j,v in enumerate(normalized(a['attacker_origin'],(0,0,0))):r[str(36+4*j)]=v
19
+ self.assertEqual(p['event_record'],r)
20
+ def test_weapon_four_has_upper_cap_but_no_lower_cap(self):
21
+ rows=[p for p in self.ps if p['input']['weapon']==4];self.assertEqual({p['event_record']['204'] for p in rows},{(-50)&0xffffffff,99,100})
22
+ def test_zero_separation_and_exact_point_override(self):
23
+ for p in self.ps:
24
+ if p['input']['attacker_origin']==[0,0,0]:self.assertEqual([p['event_record'][str(o)] for o in (36,40,44)],[0,0,0])
25
+ self.assertEqual(p['event_record']['24'],word(1.9));self.assertEqual(p['event_record']['488'],word(1))
26
+ def test_children_and_unapplied_health(self):
27
+ self.assertEqual(len(self.ps),54)
28
+ for p in self.ps:self.assertEqual([c['target'] for c in p['execution']['calls']],[277695,60317,-107]);self.assertEqual(p['effects']['feedback'],[]);self.assertEqual(p['target_health'],100)
29
+ if __name__=='__main__':unittest.main()