qvm: hitscan speed spread
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_SPREAD_SPEED.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-spread-speed.json +0 -0
- scripts/analyze_qvm_spread_speed.py +23 -0
- scripts/test_qvm_spread_speed.py +21 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -508,3 +508,6 @@ Research progress: RE-608 [report](research/QVM_ALLOCATED_GRENADE.md); remaining
|
|
| 508 |
|
| 509 |
|
| 510 |
Research progress: RE-609 [report](research/QVM_SPREAD_PARAMETERS.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 508 |
|
| 509 |
|
| 510 |
Research progress: RE-609 [report](research/QVM_SPREAD_PARAMETERS.md); remaining native/content/runtime/platform scope stays open.
|
| 511 |
+
|
| 512 |
+
|
| 513 |
+
Research progress: RE-610 [report](research/QVM_SPREAD_SPEED.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -866,3 +866,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 866 |
|
| 867 |
|
| 868 |
**RE-609 — Shared hitscan spread parameter calculation:** 290493 reads current packed slot/mode and weapon table stride432/mode stride52 to calculate base, counter-scaled and modifier-adjusted spread terms. [Evidence](research/QVM_SPREAD_PARAMETERS.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 866 |
|
| 867 |
|
| 868 |
**RE-609 — Shared hitscan spread parameter calculation:** 290493 reads current packed slot/mode and weapon table stride432/mode stride52 to calculate base, counter-scaled and modifier-adjusted spread terms. [Evidence](research/QVM_SPREAD_PARAMETERS.md).
|
| 869 |
+
|
| 870 |
+
|
| 871 |
+
**RE-610 — Hitscan movement speed normalization and airborne floor:** 290493 normalizes velocity, applies an airborne ID14/23 floor below224.4, caps at340, then converts speed before its200 split. [Evidence](research/QVM_SPREAD_SPEED.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -828,3 +828,6 @@ Research progress: RE-608 [report](research/QVM_ALLOCATED_GRENADE.md); remaining
|
|
| 828 |
|
| 829 |
|
| 830 |
Research progress: RE-609 [report](research/QVM_SPREAD_PARAMETERS.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 828 |
|
| 829 |
|
| 830 |
Research progress: RE-609 [report](research/QVM_SPREAD_PARAMETERS.md); remaining native/content/runtime/platform scope stays open.
|
| 831 |
+
|
| 832 |
+
|
| 833 |
+
Research progress: RE-610 [report](research/QVM_SPREAD_SPEED.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -732,3 +732,8 @@ Full-pool retry relaxes the recent-free guard; source count1022 enters diagnosti
|
|
| 732 |
## 2026-10-20 — RE-609 Shared hitscan spread parameter calculation (separate task commit)
|
| 733 |
|
| 734 |
290493 reads current packed slot/mode and weapon table stride432/mode stride52 to calculate base, counter-scaled and modifier-adjusted spread terms. 144 weapon/mode/flag/ground/modifier/counter fixtures match an independent source-order f32 oracle for eight locals and the velocity copy. Full suite: 938 tests pass. Report regenerates byte-identically (150821 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 732 |
## 2026-10-20 — RE-609 Shared hitscan spread parameter calculation (separate task commit)
|
| 733 |
|
| 734 |
290493 reads current packed slot/mode and weapon table stride432/mode stride52 to calculate base, counter-scaled and modifier-adjusted spread terms. 144 weapon/mode/flag/ground/modifier/counter fixtures match an independent source-order f32 oracle for eight locals and the velocity copy. Full suite: 938 tests pass. Report regenerates byte-identically (150821 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 735 |
+
|
| 736 |
+
|
| 737 |
+
## 2026-10-20 — RE-610 Hitscan movement speed normalization and airborne floor (separate task commit)
|
| 738 |
+
|
| 739 |
+
290493 normalizes velocity, applies an airborne ID14/23 floor below224.4, caps at340, then converts speed before its200 split. 48 velocity/ID/ground fixtures reproduce source-order f32 math independently, including the discontinuity at224.4. Full suite: 941 tests pass. Report regenerates byte-identically (101488 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
|
@@ -871,3 +871,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 871 |
|
| 872 |
|
| 873 |
- [x] RE-609 Shared hitscan spread parameter calculation ([report](research/QVM_SPREAD_PARAMETERS.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 871 |
|
| 872 |
|
| 873 |
- [x] RE-609 Shared hitscan spread parameter calculation ([report](research/QVM_SPREAD_PARAMETERS.md)).
|
| 874 |
+
|
| 875 |
+
|
| 876 |
+
- [x] RE-610 Hitscan movement speed normalization and airborne floor ([report](research/QVM_SPREAD_SPEED.md)).
|
docs/research/QVM_SPREAD_SPEED.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hitscan movement speed normalization and airborne floor
|
| 2 |
+
|
| 3 |
+
RE-610. Reproduce with `python3 scripts/analyze_qvm_spread_speed.py`; check with `python3 scripts/test_qvm_spread_speed.py`. The [machine report](qvm-spread-speed.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Actual290807–290968 follows the parameter prefix. Supplied native−107 computes f32 sqrt; source normalizes PS32 velocity into local12/16/20 when nonzero. For IDs14/23 while ground==1023, length strictly below fileword1130391142 (~224.4) becomes340. Equality does not floor, producing a non-monotonic spread input across that threshold. All lengths then cap at340, multiply by radians literal1016003125 and0.01, and only then split excess above200 into local92. For the tested finite nonnegative lengths, the converted value stays below0.06 and excess remains0; do not reinterpret the source as a raw-speed200 split. Local44 is table20×0.4×0.75 in source f32 order. Zero velocity retains zero normalization. Random sampling, trig offsets and endpoint writes remain pending.
|
| 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
|
@@ -429,3 +429,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 429 |
|
| 430 |
|
| 431 |
[RE-609: Shared hitscan spread parameter calculation](QVM_SPREAD_PARAMETERS.md). Reproduce with `python3 scripts/analyze_qvm_spread_parameters.py`; check with `python3 scripts/test_qvm_spread_parameters.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 429 |
|
| 430 |
|
| 431 |
[RE-609: Shared hitscan spread parameter calculation](QVM_SPREAD_PARAMETERS.md). Reproduce with `python3 scripts/analyze_qvm_spread_parameters.py`; check with `python3 scripts/test_qvm_spread_parameters.py`.
|
| 432 |
+
|
| 433 |
+
|
| 434 |
+
[RE-610: Hitscan movement speed normalization and airborne floor](QVM_SPREAD_SPEED.md). Reproduce with `python3 scripts/analyze_qvm_spread_speed.py`; check with `python3 scripts/test_qvm_spread_speed.py`.
|
docs/research/qvm-spread-speed.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_spread_speed.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""290493 velocity normalization, airborne floor and movement spread split."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source,execute
|
| 6 |
+
from qvm_server_fire_support import seed
|
| 7 |
+
from analyze_qvm_spread_parameters import parameters,LOCAL
|
| 8 |
+
from analyze_qvm_acceleration import PS,word
|
| 9 |
+
from analyze_qvm_slide_prefix import vec
|
| 10 |
+
from analyze_qvm import write_json
|
| 11 |
+
|
| 12 |
+
def speed(ins,m):
|
| 13 |
+
m,p=parameters(ins,m);m,_,r=execute(ins,290807,290969,m,(0,0,0),LOCAL)
|
| 14 |
+
return m,{'parameters':p,'execution':r,'normalized_velocity':vec(m,LOCAL+12),'locals':{str(o):m[LOCAL+o]&0xffffffff for o in [24,44,92]}}
|
| 15 |
+
|
| 16 |
+
def main():
|
| 17 |
+
q,raw,h,ins=source();rows=[]
|
| 18 |
+
for ident,ground,velocity in itertools.product([2,14,23],[0,1023],[(0,0,0),(3,4,0),(200,0,0),(224.39,0,0),(224.4,0,0),(225,0,0),(340,0,0),(600,-800,0)]):
|
| 19 |
+
m=seed(raw,h,ident);m[PS+144]=0;m[PS+312]=ident;m[PS+68]=ground
|
| 20 |
+
for j,v in enumerate(velocity):m[PS+32+4*j]=word(v)
|
| 21 |
+
rows.append(speed(ins,m)[1])
|
| 22 |
+
write_json(Path('docs/research/qvm-spread-speed.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual parameters+290807–290968; supplied f32 sqrt. No random draws/trig/endpoint/contact. Literal airborne floor and operation order retained.'})
|
| 23 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_spread_speed.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,math,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import word,n,f
|
| 4 |
+
|
| 5 |
+
def expected(p):
|
| 6 |
+
a=p['parameters']['initial'];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]))));normalized=[word(f(x*f(1/length))) for x in v] if length else list(a['velocity']);speed=length
|
| 7 |
+
if a['id'] in [14,23] and a['ground']==1023 and speed<n(1130391142):speed=340.0
|
| 8 |
+
speed=min(speed,340.0);speed=f(f(n(1016003125)*speed)*n(1008981770));excess=f(speed-200) if speed>200 else 0.0;speed=f(speed-excess);half=f(f(n(a['table']['20'])*n(1053609165))*n(1061158912))
|
| 9 |
+
return normalized,{'24':word(speed),'44':word(half),'92':word(excess)}
|
| 10 |
+
class SpreadSpeedTests(unittest.TestCase):
|
| 11 |
+
@classmethod
|
| 12 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-spread-speed.json').read_text())
|
| 13 |
+
def test_independent_velocity_and_scalar_oracle(self):
|
| 14 |
+
self.assertEqual(len(self.r['probes']),48)
|
| 15 |
+
for p in self.r['probes']:
|
| 16 |
+
velocity,locals_=expected(p);self.assertEqual(p['normalized_velocity'],velocity);self.assertEqual(p['locals'],locals_)
|
| 17 |
+
def test_airborne_floor_strictness_and_non_monotonicity(self):
|
| 18 |
+
rows=[p for p in self.r['probes'] if p['parameters']['initial']['id']==14 and p['parameters']['initial']['ground']==1023];low=next(p for p in rows if p['parameters']['initial']['velocity'][0]==word(224.39));at=next(p for p in rows if p['parameters']['initial']['velocity'][0]==word(224.4));self.assertGreater(n(low['locals']['24']),n(at['locals']['24']))
|
| 19 |
+
def test_only_actual_sqrt_child(self):
|
| 20 |
+
for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[-107]);self.assertEqual(p['locals']['92'],0)
|
| 21 |
+
if __name__=='__main__':unittest.main()
|