qvm: server event queue routing
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_SERVER_EVENT_ROUTE.md +11 -0
- docs/research/README.md +3 -0
- docs/research/qvm-server-event-route.json +0 -0
- scripts/analyze_qvm_server_event_route.py +22 -0
- scripts/qvm_server_fire_support.py +27 -0
- scripts/test_qvm_server_event_route.py +23 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -460,3 +460,6 @@ Research progress: RE-590 [report](research/QVM_WEAPON_COMPLETE_BODY.md); remain
|
|
| 460 |
|
| 461 |
|
| 462 |
Research progress: RE-591 [report](research/QVM_FIRE_SEQUENCES.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
|
| 461 |
|
| 462 |
Research progress: RE-591 [report](research/QVM_FIRE_SEQUENCES.md); remaining native/content/runtime/platform scope stays open.
|
| 463 |
+
|
| 464 |
+
|
| 465 |
+
Research progress: RE-593 [report](research/QVM_SERVER_EVENT_ROUTE.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -818,3 +818,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 818 |
|
| 819 |
|
| 820 |
**RE-591 — Timer-coupled firing sequences and actual outer publication:** Actual outer reset/timer/main-suffix/publication segments connect complete weapon effects to event31; three burst substeps retain one request and publish once, with independently checked selection/reload/last-round sequences. [Evidence](research/QVM_FIRE_SEQUENCES.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 818 |
|
| 819 |
|
| 820 |
**RE-591 — Timer-coupled firing sequences and actual outer publication:** Actual outer reset/timer/main-suffix/publication segments connect complete weapon effects to event31; three burst substeps retain one request and publish once, with independently checked selection/reload/last-round sequences. [Evidence](research/QVM_FIRE_SEQUENCES.md).
|
| 821 |
+
|
| 822 |
+
|
| 823 |
+
**RE-593 — Server event queue window and firing branch routing:** 151254 consumes at most the latest two ring events using a signed old-sequence clamp; event31 routes to151634, while other recognized consumers are stopped explicitly. [Evidence](research/QVM_SERVER_EVENT_ROUTE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -778,3 +778,6 @@ The [RE-582–591 firing batch](research/QVM_FIRING_BATCH.md) completes the boun
|
|
| 778 |
|
| 779 |
|
| 780 |
Research progress: RE-591 [report](research/QVM_FIRE_SEQUENCES.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 778 |
|
| 779 |
|
| 780 |
Research progress: RE-591 [report](research/QVM_FIRE_SEQUENCES.md); remaining native/content/runtime/platform scope stays open.
|
| 781 |
+
|
| 782 |
+
|
| 783 |
+
Research progress: RE-593 [report](research/QVM_SERVER_EVENT_ROUTE.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -650,3 +650,8 @@ The entire50746 QVM body now executes with recovered children and agrees with in
|
|
| 650 |
Actual outer reset/timer/main-suffix/publication segments connect complete weapon effects to event31; three burst substeps retain one request and publish once, with independently checked selection/reload/last-round sequences. Four multi-call scenarios check every timer/reset handoff and explicit state timelines; actual93→21→31 publication verifies order, cached ID/magazine, parameters and ring wrap. Full suite: 879 tests pass. Report regenerates byte-identically (216110 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 651 |
|
| 652 |
RE-591 additional regression:19 related reports from RE-571–580 and RE-582–590 regenerate byte-identically. Complete-body composition and repeated suffix calls add no original assets or Rust runtime changes; native firing consumers and complete original/reference ticks remain explicitly outside the completed scope.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 650 |
Actual outer reset/timer/main-suffix/publication segments connect complete weapon effects to event31; three burst substeps retain one request and publish once, with independently checked selection/reload/last-round sequences. Four multi-call scenarios check every timer/reset handoff and explicit state timelines; actual93→21→31 publication verifies order, cached ID/magazine, parameters and ring wrap. Full suite: 879 tests pass. Report regenerates byte-identically (216110 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 651 |
|
| 652 |
RE-591 additional regression:19 related reports from RE-571–580 and RE-582–590 regenerate byte-identically. Complete-body composition and repeated suffix calls add no original assets or Rust runtime changes; native firing consumers and complete original/reference ticks remain explicitly outside the completed scope.
|
| 653 |
+
|
| 654 |
+
|
| 655 |
+
## 2026-10-20 — RE-593 Server event queue window and firing branch routing (separate task commit)
|
| 656 |
+
|
| 657 |
+
151254 consumes at most the latest two ring events using a signed old-sequence clamp; event31 routes to151634, while other recognized consumers are stopped explicitly. 150 independent fixtures check old/new sequence windows, ring parity, ignored/recognized event priority, unchanged state and no fabricated child execution. Full suite: 883 tests pass. Report regenerates byte-identically (409911 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
|
@@ -820,3 +820,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 820 |
|
| 821 |
|
| 822 |
- [x] RE-591 Timer-coupled firing sequences and actual outer publication ([report](research/QVM_FIRE_SEQUENCES.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 820 |
|
| 821 |
|
| 822 |
- [x] RE-591 Timer-coupled firing sequences and actual outer publication ([report](research/QVM_FIRE_SEQUENCES.md)).
|
| 823 |
+
|
| 824 |
+
|
| 825 |
+
- [x] RE-593 Server event queue window and firing branch routing ([report](research/QVM_SERVER_EVENT_ROUTE.md)).
|
docs/research/QVM_SERVER_EVENT_ROUTE.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Server event queue window and firing branch routing
|
| 2 |
+
|
| 3 |
+
RE-593. Reproduce with `python3 scripts/analyze_qvm_server_event_route.py`; check with `python3 scripts/test_qvm_server_event_route.py`. The [machine report](qvm-server-event-route.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
151254 obtains the client pointer from entity+520, clamps the supplied old sequence upward to current sequence−2, then scans cursor<current sequence and reads event[cursor&1]. Event31 branches to151634; events21/49/50/4/12/14/15/87 route to separate consumers. Unknown events advance the cursor. The first recognized consumer is a deliberate stopping boundary.
|
| 6 |
+
|
| 7 |
+
150 finite fixtures cover ordinary signed sequences, old cursors behind/ahead, duplicates and recognized/ignored ring contents. At most two events from old history are selected. No child or game-state mutation is supplied merely to keep the loop running. Unsigned-wrap behavior and legal persisted sequence domains require original/runtime validation beyond these ordinary fixtures.
|
| 8 |
+
|
| 9 |
+
The event31 body and its289235 firing call are the next task. Other event consumers remain independent scope, rather than assumed equivalent to firing.
|
| 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
|
@@ -379,3 +379,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 379 |
|
| 380 |
|
| 381 |
[RE-591: Timer-coupled firing sequences and actual outer publication](QVM_FIRE_SEQUENCES.md). Reproduce with `python3 scripts/analyze_qvm_fire_sequences.py`; check with `python3 scripts/test_qvm_fire_sequences.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
|
| 380 |
|
| 381 |
[RE-591: Timer-coupled firing sequences and actual outer publication](QVM_FIRE_SEQUENCES.md). Reproduce with `python3 scripts/analyze_qvm_fire_sequences.py`; check with `python3 scripts/test_qvm_fire_sequences.py`.
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
[RE-593: Server event queue window and firing branch routing](QVM_SERVER_EVENT_ROUTE.md). Reproduce with `python3 scripts/analyze_qvm_server_event_route.py`; check with `python3 scripts/test_qvm_server_event_route.py`.
|
docs/research/qvm-server-event-route.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_server_event_route.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""151254 queue window and event31 routing, stopped before unresolved consumers."""
|
| 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
|
| 7 |
+
from analyze_qvm_acceleration import PS
|
| 8 |
+
from analyze_qvm import write_json
|
| 9 |
+
LOCAL=0x7a000000
|
| 10 |
+
TARGETS=[151355,151634,151660,151671,151679,151708,151739,151747]
|
| 11 |
+
|
| 12 |
+
def route(ins,m,old):
|
| 13 |
+
initial=state(m);m[LOCAL+108]=ENTITY;m[LOCAL+112]=old
|
| 14 |
+
m,c,r=execute(ins,151255,151952,m,(0,0,0),LOCAL,boundaries=TARGETS)
|
| 15 |
+
return m,{'initial':initial,'old_sequence':old,'clamped_old':m[LOCAL+112],'cursor':m[LOCAL+44],'selected_event':m.get(LOCAL+48),'execution':r,'final':state(m)}
|
| 16 |
+
|
| 17 |
+
def main():
|
| 18 |
+
q,raw,h,ins=source();rows=[]
|
| 19 |
+
for seq,old,events in itertools.product([0,1,2,3,5],[-5,0,1,3,7],[(31,0),(0,31),(31,31),(0,0),(21,31),(49,31)]):
|
| 20 |
+
m=seed(raw,h);m.update({PS+108:seq,PS+112:events[0],PS+116:events[1]});rows.append(route(ins,m,old)[1])
|
| 21 |
+
write_json(Path('docs/research/qvm-server-event-route.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Finite151254 routing only. Stops at first recognized consumer, including event31 branch151634, or void exit151952. Signed ordinary sequence fixtures; unsigned wrap legality and child outcomes unverified.'})
|
| 22 |
+
if __name__=='__main__':main()
|
scripts/qvm_server_fire_support.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Finite entity/client fixtures for server firing; engine effects remain explicit."""
|
| 2 |
+
from qvm_research_support import constants
|
| 3 |
+
from qvm_firing_support import seed as movement_seed
|
| 4 |
+
from analyze_qvm_acceleration import PS,FRAME,word
|
| 5 |
+
from analyze_qvm_slide_prefix import vec
|
| 6 |
+
from analyze_qvm_landing import queue
|
| 7 |
+
ENTITY=0x90000
|
| 8 |
+
RECORD=0xa0000
|
| 9 |
+
PROJECTILE=0xb0000
|
| 10 |
+
BASES=0xc0000
|
| 11 |
+
FORWARD=36477748
|
| 12 |
+
RIGHT=36477736
|
| 13 |
+
UP=36477724
|
| 14 |
+
MUZZLE=36477712
|
| 15 |
+
|
| 16 |
+
def seed(raw,h,ident=22):
|
| 17 |
+
m=movement_seed(raw,h,ident)
|
| 18 |
+
for o in range(0,7000,4):m.setdefault(PS+o,0)
|
| 19 |
+
for p in [ENTITY,RECORD,PROJECTILE]:
|
| 20 |
+
for o in range(0,880,4):m[p+o]=0
|
| 21 |
+
m.update(constants(raw,h,range(32688,32796,4)));m.update({ENTITY:7,ENTITY+520:PS,ENTITY+192:ident,PS+4116:10,PS+4140:1111,PS+4328:5,PS+6164:0,34992532:5000,34090788:8,35000400:0,34992500:BASES,34992508:0,35000416:0,35000420:0,35000424:0})
|
| 22 |
+
for p,values in [(ENTITY+24,(10,20,30)),(ENTITY+488,(100,200,300)),(PS+152,(0,0,0)),(FORWARD,(1,0,0)),(RIGHT,(0,-1,0)),(UP,(0,0,1)),(MUZZLE,(91,92,93))]:
|
| 23 |
+
for j,v in enumerate(values):m[p+4*j]=word(v)
|
| 24 |
+
return m
|
| 25 |
+
|
| 26 |
+
def state(m):
|
| 27 |
+
return {'entity_id':m[ENTITY],'entity_weapon':m[ENTITY+192],'slot':m[PS+144]&0xffffffff,'packed':m[PS+312+4*m[PS+144]]&0xffffffff,'timer':m[PS+44]&0xffffffff,'weapon_state':m[PS+148],'flags220':m[PS+220]&0xffffffff,'entity_flags':m[PS+104]&0xffffffff,'ground':m[PS+68],'stat4116':m[PS+4116]&0xffffffff,'field4140':m[PS+4140]&0xffffffff,'field4328':m[PS+4328]&0xffffffff,'blocked6164':m[PS+6164],'queue':queue(m),'entity_base':vec(m,ENTITY+24),'entity_origin':vec(m,ENTITY+488),'angles':vec(m,PS+152),'viewheight':m[PS+164],'forward':vec(m,FORWARD),'right':vec(m,RIGHT),'up':vec(m,UP),'muzzle':vec(m,MUZZLE)}
|
scripts/test_qvm_server_event_route.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
BRANCHES={31:151634,21:151747,49:151355,50:151355,4:151660,12:151671,14:151679,15:151739,87:151708}
|
| 4 |
+
|
| 5 |
+
def routing(p):
|
| 6 |
+
seq=p['initial']['queue']['sequence'];cursor=max(p['old_sequence'],seq-2);old=cursor;selected=None;stop=151952
|
| 7 |
+
while cursor<seq:
|
| 8 |
+
selected=p['initial']['queue']['events'][cursor&1]
|
| 9 |
+
if selected in BRANCHES:stop=BRANCHES[selected];break
|
| 10 |
+
cursor+=1
|
| 11 |
+
return old,cursor,selected,stop
|
| 12 |
+
class ServerEventRouteTests(unittest.TestCase):
|
| 13 |
+
@classmethod
|
| 14 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-server-event-route.json').read_text())
|
| 15 |
+
def test_window_cursor_and_first_branch(self):
|
| 16 |
+
self.assertEqual(len(self.r['probes']),150)
|
| 17 |
+
for p in self.r['probes']:old,cursor,selected,stop=routing(p);self.assertEqual((p['clamped_old'],p['cursor'],p['selected_event'],p['execution']['stop']),(old,cursor,selected,stop))
|
| 18 |
+
def test_two_slot_window_not_full_old_history(self):
|
| 19 |
+
for p in self.r['probes']:self.assertGreaterEqual(p['clamped_old'],p['initial']['queue']['sequence']-2)
|
| 20 |
+
def test_routing_has_no_callee_or_game_state_effect(self):
|
| 21 |
+
for p in self.r['probes']:self.assertEqual(p['initial'],p['final']);self.assertEqual(p['execution']['calls'],[])
|
| 22 |
+
def test_event31_and_other_recognized_branch_stop(self):self.assertTrue(any(p['execution']['stop']==151634 for p in self.r['probes']));self.assertTrue(any(p['execution']['stop']==151747 for p in self.r['probes']))
|
| 23 |
+
if __name__=='__main__':unittest.main()
|