qvm: grenade record construction
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_GRENADE_SETUP.md +11 -0
- docs/research/README.md +3 -0
- docs/research/qvm-grenade-setup.json +0 -0
- scripts/analyze_qvm_grenade_setup.py +37 -0
- scripts/test_qvm_grenade_setup.py +30 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -481,3 +481,6 @@ Research progress: RE-598 [report](research/QVM_TEMP_EVENT.md); remaining native
|
|
| 481 |
|
| 482 |
|
| 483 |
Research progress: RE-599 [report](research/QVM_SERVER_SHOT_SETUP.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
|
| 482 |
|
| 483 |
Research progress: RE-599 [report](research/QVM_SERVER_SHOT_SETUP.md); remaining native/content/runtime/platform scope stays open.
|
| 484 |
+
|
| 485 |
+
|
| 486 |
+
Research progress: RE-600 [report](research/QVM_GRENADE_SETUP.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -839,3 +839,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 839 |
|
| 840 |
|
| 841 |
**RE-599 — Event57 firing setup quantization and actual PRNG:** 285840 builds event57, stores trunc(forward×4096) as float direction, derives a seed byte from actual36717 xorshift, records shooter/weapon IDs and prepares295018 arguments. [Evidence](research/QVM_SERVER_SHOT_SETUP.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 839 |
|
| 840 |
|
| 841 |
**RE-599 — Event57 firing setup quantization and actual PRNG:** 285840 builds event57, stores trunc(forward×4096) as float direction, derives a seed byte from actual36717 xorshift, records shooter/weapon IDs and prepares295018 arguments. [Evidence](research/QVM_SERVER_SHOT_SETUP.md).
|
| 842 |
+
|
| 843 |
+
|
| 844 |
+
**RE-600 — Grenade record construction and inherited velocity:** 285971 looks up weapon7 mode, biases forwardZ by.2 and normalizes, builds a grenade descriptor, quantizes mode-scaled launch velocity, then adds owner and optionally matching-ground velocity. [Evidence](research/QVM_GRENADE_SETUP.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -799,3 +799,6 @@ Research progress: RE-598 [report](research/QVM_TEMP_EVENT.md); remaining native
|
|
| 799 |
|
| 800 |
|
| 801 |
Research progress: RE-599 [report](research/QVM_SERVER_SHOT_SETUP.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 799 |
|
| 800 |
|
| 801 |
Research progress: RE-599 [report](research/QVM_SERVER_SHOT_SETUP.md); remaining native/content/runtime/platform scope stays open.
|
| 802 |
+
|
| 803 |
+
|
| 804 |
+
Research progress: RE-600 [report](research/QVM_GRENADE_SETUP.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -685,3 +685,8 @@ Actual outer31 publication reaches server151634, which writes client4140=0 and43
|
|
| 685 |
## 2026-10-20 — RE-599 Event57 firing setup quantization and actual PRNG (separate task commit)
|
| 686 |
|
| 687 |
285840 builds event57, stores trunc(forward×4096) as float direction, derives a seed byte from actual36717 xorshift, records shooter/weapon IDs and prepares295018 arguments. 24 independent full-record/PRNG fixtures check fractional/negative quantization, seed0/1/hex/unsigned−1, tempEntity handoff, link-time ordering and exact opaque-call ABI. Full suite: 907 tests pass. Report regenerates byte-identically (1527580 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 685 |
## 2026-10-20 — RE-599 Event57 firing setup quantization and actual PRNG (separate task commit)
|
| 686 |
|
| 687 |
285840 builds event57, stores trunc(forward×4096) as float direction, derives a seed byte from actual36717 xorshift, records shooter/weapon IDs and prepares295018 arguments. 24 independent full-record/PRNG fixtures check fractional/negative quantization, seed0/1/hex/unsigned−1, tempEntity handoff, link-time ordering and exact opaque-call ABI. Full suite: 907 tests pass. Report regenerates byte-identically (1527580 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 688 |
+
|
| 689 |
+
|
| 690 |
+
## 2026-10-20 — RE-600 Grenade record construction and inherited velocity (separate task commit)
|
| 691 |
+
|
| 692 |
+
285971 looks up weapon7 mode, biases forwardZ by.2 and normalizes, builds a grenade descriptor, quantizes mode-scaled launch velocity, then adds owner and optionally matching-ground velocity. 37 independent full-record fixtures check slot0/15/missing lookup, two source speeds, zero after bias, allocation/query ABI and all position/trajectory/ownership/think fields. Full suite: 911 tests pass. Report regenerates byte-identically (649857 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
|
@@ -841,3 +841,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 841 |
|
| 842 |
|
| 843 |
- [x] RE-599 Event57 firing setup quantization and actual PRNG ([report](research/QVM_SERVER_SHOT_SETUP.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 841 |
|
| 842 |
|
| 843 |
- [x] RE-599 Event57 firing setup quantization and actual PRNG ([report](research/QVM_SERVER_SHOT_SETUP.md)).
|
| 844 |
+
|
| 845 |
+
|
| 846 |
+
- [x] RE-600 Grenade record construction and inherited velocity ([report](research/QVM_GRENADE_SETUP.md)).
|
docs/research/QVM_GRENADE_SETUP.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Grenade record construction and inherited velocity
|
| 2 |
+
|
| 3 |
+
RE-600. Reproduce with `python3 scripts/analyze_qvm_grenade_setup.py`; check with `python3 scripts/test_qvm_grenade_setup.py`. The [machine report](qvm-grenade-setup.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
File-backed classname97541 is grenade. Actual31691 finds weapon7's first slot and decodes its mode; a missing−1 slot reads the explicitly supplied adjacent PS308 fixture rather than inventing a valid slot. Global forwardZ adds source.2, then actual float operations use a supplied finite sqrt to normalize unless zero.
|
| 6 |
+
|
| 7 |
+
With a supplied277165 record, the body initializes type/trajectory/owner/flags/mask/timing and numeric scalar fields and copies global muzzle to base/live origin. Direction×source speed7304+52×mode is truncated to integer then converted back to float, after which owner PS velocity is added. A supplied276433 query result contributes its velocity only when its entity ID matches PS ground.
|
| 8 |
+
|
| 9 |
+
37 fixtures reconstruct every record word and transformed forward vector independently. The exact query hash/arguments and supplied record pointer are retained. Allocator/query engine effects, entity linking, trajectory integration, explosion and damage are not executed. Construction alone does not prove a working projectile or native outcome.
|
| 10 |
+
|
| 11 |
+
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
|
@@ -400,3 +400,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 400 |
|
| 401 |
|
| 402 |
[RE-599: Event57 firing setup quantization and actual PRNG](QVM_SERVER_SHOT_SETUP.md). Reproduce with `python3 scripts/analyze_qvm_server_shot_setup.py`; check with `python3 scripts/test_qvm_server_shot_setup.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
|
| 401 |
|
| 402 |
[RE-599: Event57 firing setup quantization and actual PRNG](QVM_SERVER_SHOT_SETUP.md). Reproduce with `python3 scripts/analyze_qvm_server_shot_setup.py`; check with `python3 scripts/test_qvm_server_shot_setup.py`.
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
[RE-600: Grenade record construction and inherited velocity](QVM_GRENADE_SETUP.md). Reproduce with `python3 scripts/analyze_qvm_grenade_setup.py`; check with `python3 scripts/test_qvm_grenade_setup.py`.
|
docs/research/qvm-grenade-setup.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_grenade_setup.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""285971 construction: lookup, biased normalized direction, record and inherited velocity."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source,execute
|
| 6 |
+
from qvm_server_fire_support import seed,state,ENTITY,PROJECTILE,BASES,FORWARD,MUZZLE
|
| 7 |
+
from analyze_qvm_temp_event import record
|
| 8 |
+
from analyze_qvm_weapon_lookup import lookup
|
| 9 |
+
from analyze_qvm_acceleration import PS,word
|
| 10 |
+
from analyze_qvm_slide_prefix import vec
|
| 11 |
+
from analyze_qvm import write_json
|
| 12 |
+
LOCAL=0x7f000000
|
| 13 |
+
|
| 14 |
+
def grenade(ins,m,query_pointer=0):
|
| 15 |
+
initial=state(m);before=record(m);weapons=[m[PS+312+4*j]&0xffffffff for j in range(16)];minus=m[PS+308]&0xffffffff;m[LOCAL+84]=ENTITY;query=[];speeds={str(mode):m[7304+52*mode]&0xffffffff for mode in [0,1]};velocity=vec(m,PS+32);ground_velocity=vec(m,BASES+36)
|
| 16 |
+
def allocated(i,m,a,c):return m,c,PROJECTILE,{'supplied_record_pointer':PROJECTILE,'allocator_not_executed':True}
|
| 17 |
+
def find(i,m,a,c):r={'arguments':a,'supplied_pointer':query_pointer,'entity_id':m.get(query_pointer),'query_not_executed':True};query.append(r);return m,c,query_pointer,r
|
| 18 |
+
m,c,r=execute(ins,285972,286471,m,(0,0,0),LOCAL,{31691:lookup,277165:allocated,276433:find});slot=r['children'][0]['effect']['execution']['return'];mode=m[LOCAL+24]
|
| 19 |
+
return m,{'initial':initial,'initial_record':before,'weapon_slots':weapons,'slot_minus1_word':minus,'lookup_slot':slot,'mode':mode,'speeds':speeds,'word7224':m[7224]&0xffffffff,'time':m[34992532],'owner_velocity':velocity,'ground_velocity':ground_velocity,'query':query,'execution':r,'final_record':record(m),'final':state(m)}
|
| 20 |
+
|
| 21 |
+
def main():
|
| 22 |
+
q,raw,h,ins=source();rows=[]
|
| 23 |
+
for fw,slot,mode,query_kind in itertools.product([(1,0,0),(.6,-.25,.8),(0,0,-.2)],[0,15],[0,1],['none','match','other']):
|
| 24 |
+
m=seed(raw,h,7)
|
| 25 |
+
for j in range(16):m[PS+312+4*j]=22
|
| 26 |
+
m[PS+312+4*slot]=7|(mode<<16);m[PS+308]=7
|
| 27 |
+
for o in range(0,880,4):m[BASES+o]=0
|
| 28 |
+
m[BASES]=8 if query_kind=='match' else 9;m[PS+68]=8
|
| 29 |
+
for p,v in [(FORWARD,fw),(BASES+36,(.5,-.25,2))]:
|
| 30 |
+
for j,x in enumerate(v):m[p+4*j]=word(x)
|
| 31 |
+
rows.append(grenade(ins,m,0 if query_kind=='none' else BASES)[1])
|
| 32 |
+
m=seed(raw,h,7);m[PS+312]=22;m[PS+308]=7|(1<<16)
|
| 33 |
+
for o in range(0,880,4):m[BASES+o]=0
|
| 34 |
+
rows.append(grenade(ins,m)[1])
|
| 35 |
+
classname=raw[h['data_offset']+97541:].split(b'\0',1)[0].decode()
|
| 36 |
+
write_json(Path('docs/research/qvm-grenade-setup.json'),{'source':q['source'],'sha256':q['sha256'],'classname':{'address':97541,'text':classname},'probes':rows,'limits':'Complete finite285971 with actual31691/supplied sqrt, explicit allocator and276433 query responses. Missing lookup−1 uses supplied PS308 fixture, not asserted legal. No entity allocation/link/trajectory physics/explosion or damage executes.'})
|
| 37 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_grenade_setup.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest,copy,math
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import word,n,f
|
| 4 |
+
|
| 5 |
+
def normalized(p):
|
| 6 |
+
v=list(map(n,p['initial']['forward']));v[2]=f(v[2]+n(1045220557));length=f(math.sqrt(f(f(f(v[0]*v[0])+f(v[1]*v[1]))+f(v[2]*v[2]))))
|
| 7 |
+
return [f(x*f(1/length)) for x in v] if length else v
|
| 8 |
+
|
| 9 |
+
def projectile(p):
|
| 10 |
+
r=copy.deepcopy(p['initial_record']);r.update({str(k):v&0xffffffff for k,v in {536:97541,540:513611514,644:p['time']+2500,648:223156,4:3,424:160,192:7,8:256,512:p['initial']['entity_id'],516:589824,692:90,696:180,700:300,704:p['word7224'],708:p['word7224'],588:100663297,624:0,12:5,16:p['time']-50}.items()})
|
| 11 |
+
direction=normalized(p);velocity=[f(float(int(f(x*n(p['speeds'][str(p['mode'])]))))) for x in direction];velocity=[f(x+n(y)) for x,y in zip(velocity,p['owner_velocity'])]
|
| 12 |
+
if p['query'][0]['supplied_pointer'] and p['query'][0]['entity_id']==p['initial']['ground']:velocity=[f(x+n(y)) for x,y in zip(velocity,p['ground_velocity'])]
|
| 13 |
+
for base in [24,488]:
|
| 14 |
+
for j,v in enumerate(p['initial']['muzzle']):r[str(base+4*j)]=v
|
| 15 |
+
for j,v in enumerate(velocity):r[str(36+4*j)]=word(v)
|
| 16 |
+
return r
|
| 17 |
+
class GrenadeSetupTests(unittest.TestCase):
|
| 18 |
+
@classmethod
|
| 19 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-grenade-setup.json').read_text())
|
| 20 |
+
def test_exact_projectile_descriptor_and_velocity(self):
|
| 21 |
+
self.assertEqual(len(self.r['probes']),37)
|
| 22 |
+
for p in self.r['probes']:self.assertEqual(p['final_record'],projectile(p));a=copy.deepcopy(p['initial']);a['forward']=list(map(word,normalized(p)));self.assertEqual(p['final'],a)
|
| 23 |
+
def test_actual_first16_lookup_and_mode_source(self):
|
| 24 |
+
for p in self.r['probes']:
|
| 25 |
+
slot=next((j for j,v in enumerate(p['weapon_slots']) if v&255==7),-1);packed=p['weapon_slots'][slot] if slot>=0 else p['slot_minus1_word'];self.assertEqual((p['lookup_slot'],p['mode']),(slot,packed>>16&255))
|
| 26 |
+
def test_actual_child_order_and_supplied_engine_contracts(self):
|
| 27 |
+
for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[31691,-107,277165,276433]);self.assertEqual(p['query'][0]['arguments'],{'8':0,'12':-913528516});self.assertTrue(p['query'][0]['query_not_executed'])
|
| 28 |
+
def test_file_classname_zero_direction_and_missing_slot_fixture(self):
|
| 29 |
+
self.assertEqual(self.r['classname'],{'address':97541,'text':'grenade'});self.assertTrue(any(all(v==0 for v in normalized(p)) for p in self.r['probes']));self.assertEqual(self.r['probes'][-1]['lookup_slot'],-1)
|
| 30 |
+
if __name__=='__main__':unittest.main()
|