nmarshall commited on
Commit
3760254
·
1 Parent(s): d24d8b9

qvm: damage descriptors and range term

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -775,3 +775,6 @@ Research progress: RE-701 [report](research/RUST_MD3.md); remaining native/conte
775
 
776
 
777
  Research progress: RE-703 [report](research/QVM_DAMAGE_PROTECTION.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
775
 
776
 
777
  Research progress: RE-703 [report](research/QVM_DAMAGE_PROTECTION.md); remaining native/content/runtime/platform scope stays open.
778
+
779
+
780
+ Research progress: RE-704 [report](research/QVM_DAMAGE_RANGE.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -1121,3 +1121,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
1121
 
1122
 
1123
  **RE-703 — Damage protection and armor location selection:** 289594 rejects mode9 and strictly active spawn protection before location output; actual32155/32117 reclassifies head/torso using live inventory low bytes and health, excluding slot16. [Evidence](research/QVM_DAMAGE_PROTECTION.md).
 
 
 
 
1121
 
1122
 
1123
  **RE-703 — Damage protection and armor location selection:** 289594 rejects mode9 and strictly active spawn protection before location output; actual32155/32117 reclassifies head/torso using live inventory low bytes and health, excluding slot16. [Evidence](research/QVM_DAMAGE_PROTECTION.md).
1124
+
1125
+
1126
+ **RE-704 — Damage descriptor and cubic range term:** 289762 selects two words at4068+432×weapon+8×location and independently computes weapon4 ratio clamp and cubic complement using context84. [Evidence](research/QVM_DAMAGE_RANGE.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1110,3 +1110,6 @@ RE-692–701 batch complete: [original models and Rust asset foundation](researc
1110
 
1111
 
1112
  Research progress: RE-703 [report](research/QVM_DAMAGE_PROTECTION.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
1110
 
1111
 
1112
  Research progress: RE-703 [report](research/QVM_DAMAGE_PROTECTION.md); remaining native/content/runtime/platform scope stays open.
1113
+
1114
+
1115
+ Research progress: RE-704 [report](research/QVM_DAMAGE_RANGE.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -1157,3 +1157,8 @@ A dependency-free Rust asset crate parses all619 originals with Python parity fo
1157
  ## 2026-10-21 — RE-703 Damage protection and armor location selection (separate task commit)
1158
 
1159
  289594 rejects mode9 and strictly active spawn protection before location output; actual32155/32117 reclassifies head/torso using live inventory low bytes and health, excluding slot16. 356 gate/inventory fixtures and independent boundary/notification/location oracles pass. Full suite: 1263 tests pass. Report regenerates byte-identically (653493 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
1157
  ## 2026-10-21 — RE-703 Damage protection and armor location selection (separate task commit)
1158
 
1159
  289594 rejects mode9 and strictly active spawn protection before location output; actual32155/32117 reclassifies head/torso using live inventory low bytes and health, excluding slot16. 356 gate/inventory fixtures and independent boundary/notification/location oracles pass. Full suite: 1263 tests pass. Report regenerates byte-identically (653493 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
1160
+
1161
+
1162
+ ## 2026-10-21 — RE-704 Damage descriptor and cubic range term (separate task commit)
1163
+
1164
+ 289762 selects two words at4068+432×weapon+8×location and independently computes weapon4 ratio clamp and cubic complement using context84. 208 original-table and explicit range boundary fixtures pass exact float32 and descriptor oracles. Full suite: 1267 tests pass. Report regenerates byte-identically (341409 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
@@ -1153,3 +1153,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1153
 
1154
 
1155
  - [x] RE-703 Damage protection and armor location selection ([report](research/QVM_DAMAGE_PROTECTION.md)).
 
 
 
 
1153
 
1154
 
1155
  - [x] RE-703 Damage protection and armor location selection ([report](research/QVM_DAMAGE_PROTECTION.md)).
1156
+
1157
+
1158
+ - [x] RE-704 Damage descriptor and cubic range term ([report](research/QVM_DAMAGE_RANGE.md)).
docs/research/QVM_DAMAGE_RANGE.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Damage descriptor and cubic range term
2
+
3
+ RE-704. Reproduce with `python3 scripts/analyze_qvm_damage_range.py`; check with `python3 scripts/test_qvm_damage_range.py`. The [machine report](qvm-damage-range.json) retains source identity and bounded fixtures.
4
+
5
+ Actual289762–289861 uses signed positive descriptor4188+432×weapon as range. Only weapon4 computes context84/(range×10), clamps to[0,1], and stores (1−ratio) cubed with source-order float32 products. Nonpositive range leaves ratio0 and complement1. This is a local term, not yet the final damage factor. The location selects a pair at4068+432×weapon+8×location: first float factor and second wound word. Source descriptor words are preserved; range overrides are explicitly labeled synthetic fixtures. No external calls or health writes occur.
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
@@ -711,3 +711,6 @@ The extension collector adds five focused tests for native tail calls, command-r
711
 
712
 
713
  [RE-703: Damage protection and armor location selection](QVM_DAMAGE_PROTECTION.md). Reproduce with `python3 scripts/analyze_qvm_damage_protection.py`; check with `python3 scripts/test_qvm_damage_protection.py`.
 
 
 
 
711
 
712
 
713
  [RE-703: Damage protection and armor location selection](QVM_DAMAGE_PROTECTION.md). Reproduce with `python3 scripts/analyze_qvm_damage_protection.py`; check with `python3 scripts/test_qvm_damage_protection.py`.
714
+
715
+
716
+ [RE-704: Damage descriptor and cubic range term](QVM_DAMAGE_RANGE.md). Reproduce with `python3 scripts/analyze_qvm_damage_range.py`; check with `python3 scripts/test_qvm_damage_range.py`.
docs/research/qvm-damage-range.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_damage_range.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Actual weapon/location descriptor selection and weapon4 cubic distance term."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source
6
+ from qvm_damage_support import seed,run,L
7
+ from analyze_qvm_acceleration import word
8
+ from analyze_qvm import write_json
9
+
10
+ def probe(ins,raw,h,a):
11
+ m=seed(raw,h,**a);w=a['weapon'];loc=a['location']
12
+ if 'range' in a:m[4188+432*w]=a['range']
13
+ table=4068+432*w+8*loc;descriptor=[m[table],m[table+4]];maximum=m[4188+432*w]
14
+ m,p=run(ins,m,289762,289862);p.update({'input':a,'table_address':table,'descriptor_words':descriptor,'range_integer':maximum,'distance_word':word(a.get('distance',0))});return p
15
+
16
+ def main():
17
+ q,raw,h,ins=source();cases=[dict(weapon=w,location=loc,distance=d) for w,loc,d in itertools.product([3,4,24],range(15),[0,1500,3000,4500])]
18
+ cases += [dict(weapon=4,location=1,distance=d,range=r) for r,d in itertools.product([-1,0,1,300],[-10,0,5,10,2999,3000,3001])]
19
+ write_json(Path('docs/research/qvm-damage-range.json'),{'source':q['source'],'sha256':q['sha256'],'probes':[probe(ins,raw,h,a) for a in cases],'limits':'Actual289762..289861. Descriptors and default range from original file data; explicit range overrides probe boundaries. Cubic term stored separately from descriptor factor here.'})
20
+ if __name__=='__main__':main()
scripts/test_qvm_damage_range.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,n,f
4
+ class DamageRangeTests(unittest.TestCase):
5
+ @classmethod
6
+ def setUpClass(cls):cls.ps=json.loads(Path('docs/research/qvm-damage-range.json').read_text())['probes']
7
+ def test_exact_descriptor_pair_and_stride(self):
8
+ for p in self.ps:
9
+ a=p['input'];self.assertEqual(p['table_address'],4068+432*a['weapon']+8*a['location']);self.assertEqual([p['final']['locals'][k] for k in ['20','24']],p['descriptor_words'])
10
+ def test_independent_cubic_float32_term(self):
11
+ for p in self.ps:
12
+ a=p['input'];r=0.;cubic=1.
13
+ if a['weapon']==4 and p['range_integer']>0:
14
+ r=min(1.,max(0.,f(n(p['distance_word'])/f(p['range_integer']*10))))
15
+ v=f(1.-r);cubic=f(f(v*v)*v)
16
+ self.assertEqual(p['final']['locals']['32'],word(r));self.assertEqual(p['final']['locals']['36'],word(cubic))
17
+ def test_no_calls_or_early_return(self):
18
+ for p in self.ps:self.assertEqual(p['execution']['calls'],[]);self.assertIsNone(p['execution']['return']);self.assertEqual(p['execution']['stop'],289862)
19
+ def test_provenance_and_domains(self):
20
+ self.assertEqual(len(self.ps),208);self.assertTrue(any(p['range_integer']<=0 for p in self.ps));self.assertTrue(any(p['range_integer']==300 and p['input']['distance']==3001 for p in self.ps))
21
+ if __name__=='__main__':unittest.main()