qvm: main consumer chains
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +3 -0
- docs/PROVISIONAL_TODO.md +5 -0
- docs/RESEARCH_LEDGER.md +5 -0
- docs/REVERSE_ENGINEERING_TODO.md +5 -0
- docs/research/QVM_CONSUMER_BATCH.md +46 -0
- docs/research/QVM_MAIN_CONSUMERS.md +11 -0
- docs/research/README.md +5 -0
- docs/research/qvm-main-consumers.json +0 -0
- scripts/analyze_qvm_main_consumers.py +41 -0
- scripts/test_qvm_main_consumers.py +56 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -397,3 +397,6 @@ Research progress: RE-567 [report](research/QVM_LOCOMOTION_PREFIX.md); remaining
|
|
| 397 |
|
| 398 |
|
| 399 |
Research progress: RE-568 [report](research/QVM_LOCOMOTION.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
|
| 398 |
|
| 399 |
Research progress: RE-568 [report](research/QVM_LOCOMOTION.md); remaining native/content/runtime/platform scope stays open.
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
Research progress: RE-569 [report](research/QVM_MAIN_CONSUMERS.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -755,3 +755,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 755 |
|
| 756 |
|
| 757 |
**RE-568 — Complete locomotion gait bob and footstep consumer:** Complete47884 selects grounded stance/gait requests, advances a masked bob cycle at.3 or.4 rates, and emits surface39, shallow32 or water41 events only on cycle crossings with route-specific suppression. [Evidence](research/QVM_LOCOMOTION.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 755 |
|
| 756 |
|
| 757 |
**RE-568 — Complete locomotion gait bob and footstep consumer:** Complete47884 selects grounded stance/gait requests, advances a masked bob cycle at.3 or.4 rates, and emits surface39, shallow32 or water41 events only on cycle crossings with route-specific suppression. [Evidence](research/QVM_LOCOMOTION.md).
|
| 758 |
+
|
| 759 |
+
|
| 760 |
+
**RE-569 — Main request and independently bounded animation consumer chains:** Actual54444 reload/interaction order exposes timer interference before the weapon prefix; a separate54455 torso/locomotion/water segment verifies animation and queue overwrite order without bridging the unrecovered weapon body. [Evidence](research/QVM_MAIN_CONSUMERS.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -709,3 +709,8 @@ Research progress: RE-567 [report](research/QVM_LOCOMOTION_PREFIX.md); remaining
|
|
| 709 |
|
| 710 |
|
| 711 |
Research progress: RE-568 [report](research/QVM_LOCOMOTION.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 709 |
|
| 710 |
|
| 711 |
Research progress: RE-568 [report](research/QVM_LOCOMOTION.md); remaining native/content/runtime/platform scope stays open.
|
| 712 |
+
|
| 713 |
+
The [RE-560–569 consumer batch](research/QVM_CONSUMER_BATCH.md) closes bounded freeflight, water events, torso/reload/interaction controls and locomotion. The weapon body beyond50871 still prevents a complete main tick. Prioritize the ten concrete follow-ups listed there; full native/reference/content/platform gameplay scope remains open.
|
| 714 |
+
|
| 715 |
+
|
| 716 |
+
Research progress: RE-569 [report](research/QVM_MAIN_CONSUMERS.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -541,3 +541,8 @@ RE-549–558 each has its own code/tests/report/documentation commit. All759 tes
|
|
| 541 |
## 2026-10-20 — RE-568 Complete locomotion gait bob and footstep consumer (separate task commit)
|
| 542 |
|
| 543 |
Complete47884 selects grounded stance/gait requests, advances a masked bob cycle at.3 or.4 rates, and emits surface39, shallow32 or water41 events only on cycle crossings with route-specific suppression. 120 complete fixtures independently check idle speed5 boundary, crouch/walk/run/backward/boost/special routes, class/tag torso choices, exact float bob arithmetic and surface/water event effects. Full suite: 795 tests pass. Report regenerates byte-identically (1570164 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 541 |
## 2026-10-20 — RE-568 Complete locomotion gait bob and footstep consumer (separate task commit)
|
| 542 |
|
| 543 |
Complete47884 selects grounded stance/gait requests, advances a masked bob cycle at.3 or.4 rates, and emits surface39, shallow32 or water41 events only on cycle crossings with route-specific suppression. 120 complete fixtures independently check idle speed5 boundary, crouch/walk/run/backward/boost/special routes, class/tag torso choices, exact float bob arithmetic and surface/water event effects. Full suite: 795 tests pass. Report regenerates byte-identically (1570164 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 544 |
+
|
| 545 |
+
|
| 546 |
+
## 2026-10-20 — RE-569 Main request and independently bounded animation consumer chains (separate task commit)
|
| 547 |
+
|
| 548 |
+
Actual54444 reload/interaction order exposes timer interference before the weapon prefix; a separate54455 torso/locomotion/water segment verifies animation and queue overwrite order without bridging the unrecovered weapon body. 24 request chains and18 independent animation chains check every live child handoff and exact state with independent task oracles, caller suspension and explicit no-full-tick scope. Full suite: 799 tests pass. Report regenerates byte-identically (1393581 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
|
@@ -749,3 +749,8 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 749 |
|
| 750 |
|
| 751 |
- [x] RE-568 Complete locomotion gait bob and footstep consumer ([report](research/QVM_LOCOMOTION.md)).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 749 |
|
| 750 |
|
| 751 |
- [x] RE-568 Complete locomotion gait bob and footstep consumer ([report](research/QVM_LOCOMOTION.md)).
|
| 752 |
+
|
| 753 |
+
- [ ] RE-570 Recover48798/49028 weapon selection/completion,50525 helper and50872..53045 firing/reload continuation; connect availability/resource writers and main final vector snap. Validate full source-order ticks against original execution before claiming runtime parity. Map numeric animation/audio IDs to assets and continue Rust/Bevy/Solari macOS/Linux implementation. See [consumer batch scope and next work](research/QVM_CONSUMER_BATCH.md).
|
| 754 |
+
|
| 755 |
+
|
| 756 |
+
- [x] RE-569 Main request and independently bounded animation consumer chains ([report](research/QVM_MAIN_CONSUMERS.md)).
|
docs/research/QVM_CONSUMER_BATCH.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# QVM consumer batch: RE-560–569
|
| 2 |
+
|
| 3 |
+
Ten separately committed research tasks continue the movement work into weapon request, animation, resource and event consumers. These are bounded interpretations of the verified shipped qagame instruction image, with independent formula/state tests and reproducible reports. They add no Rust gameplay or native reference execution.
|
| 4 |
+
|
| 5 |
+
| Task | Recovered scope | Evidence |
|
| 6 |
+
| --- | --- | --- |
|
| 7 |
+
| RE-560 | Complete42486 freeflight with friction, three-axis wish, acceleration and direct position | [Freeflight](QVM_FREEFLIGHT.md) |
|
| 8 |
+
| RE-561 | Complete48716 transition events and actual two-slot queue | [Water events](QVM_WATER_EVENTS.md) |
|
| 9 |
+
| RE-562 | Complete49117 torso priority and weapon-class jump dispatch | [Torso selector](QVM_TORSO_SELECTOR.md) |
|
| 10 |
+
| RE-563 | Complete49652 reload request, packed gates, timer/animation/event | [Reload request](QVM_RELOAD_REQUEST.md) |
|
| 11 |
+
| RE-564 | Complete49918 interaction with trace contract and actual32155/32117 item lookup | [Interaction](QVM_INTERACTION_REQUEST.md) |
|
| 12 |
+
| RE-565 | Complete50250 edge latch,50309 availability and50397 resource countdown | [Packed controls](QVM_PACKED_CONTROLS.md) |
|
| 13 |
+
| RE-566 | Complete49327 mode switch and bounded50746 prefix through50871 | [Weapon prefix](QVM_WEAPON_PREFIX.md) |
|
| 14 |
+
| RE-567 |47884 prefix and complete airborne branch through48713 | [Airborne locomotion](QVM_LOCOMOTION_PREFIX.md) |
|
| 15 |
+
| RE-568 | Complete47884 grounded/airborne stance, gait, bob and footsteps | [Locomotion](QVM_LOCOMOTION.md) |
|
| 16 |
+
| RE-569 | Actual main request/interaction segment leading into suspended weapon prefix; separately supplied animation/event segment | [Main consumers](QVM_MAIN_CONSUMERS.md) |
|
| 17 |
+
|
| 18 |
+
## Evidence and limits
|
| 19 |
+
|
| 20 |
+
Every task has a source-identified JSON report, a generator and four independent tests. The completed batch adds40 tests to the759-test baseline. Reports stay below the2MiB normal-Git cap; generation is deterministic. Original payloads remain outside normal Git. The bounded call driver now accepts numeric LEAVE traces without a stop field; the shared instruction evaluator itself is unchanged.
|
| 21 |
+
|
| 22 |
+
Initialized weapon words and class jump tables are file-backed evidence, not verified live configuration. Animation durations are supplied321 records, except marked boundary fixtures. Sqrt responses use finite float32 ordinary math. Interaction trace records are supplied; their geometry is not evaluated by a native collision engine. Synthetic invalid/overflow inputs isolate VM arithmetic and do not establish legal gameplay domains.
|
| 23 |
+
|
| 24 |
+
RE-569 does **not** complete a main tick. It evaluates54444..54451 (reload and interaction), then inspects50746 only through50871, keeping the caller suspended before any missing weapon continuation returns. The separate54455..54463 segment starts from explicitly supplied post-weapon state. It does not transfer state across the missing50872..53045 body. Final native vector snapping54471 is also omitted.
|
| 25 |
+
|
| 26 |
+
## Concrete findings
|
| 27 |
+
|
| 28 |
+
- Freeflight multiplies command scale by1.5 before three-axis wish construction, uses coefficient8 acceleration and integrates only when a velocity component has absolute value strictly above1.
|
| 29 |
+
- Water0→3 and3→0 each produce two events. Entry101 requires vertical velocity strictly below−500; equality selects100.
|
| 30 |
+
- Reload tests magazine equality with capacity, replaces a timer even if it was already positive, and does not itself transfer ammo. In the main segment its timer blocks the immediately following interaction, then the weapon prefix subtracts the current dt.
|
| 31 |
+
- Interaction's item19 check searches only16 low-byte inventory slots and requires positive health; it selects750 versus1500. Its direct action branch uses1000 and reverses animation/event call order.
|
| 32 |
+
- Resource drain uses the full dt on the tick a countdown expires. The weapon prefix can retain a negative weapon timer before later, unrecovered processing.
|
| 33 |
+
- Locomotion speed is FRAME216, distinct from PS216. Bob crossings drive surface/water events; surface8192 suppresses the dry footstep. Later locomotion torso requests can supersede the earlier torso selector when helper guards allow.
|
| 34 |
+
|
| 35 |
+
## Next work
|
| 36 |
+
|
| 37 |
+
1. Recover weapon selection48798 and completion49028, including inventory slots, packed mode, timer and animation/event children.
|
| 38 |
+
2. Recover helper50525 with its native request ABI and all callers.
|
| 39 |
+
3. Partition50746 from50872 onward into reload, firing, delay, mode and special-weapon branches; record every unresolved child before interpreting each branch.
|
| 40 |
+
4. Reconstruct actual ammunition transfer, projectile/hitscan requests, spread/recoil and firing-event consumers without treating opaque native calls as successful.
|
| 41 |
+
5. Connect50309 availability to real callers and configuration writers; identify PS188/196 resource semantics and legal rate domains.
|
| 42 |
+
6. Complete the main final native vector snap and remaining prefix/scheduler effects, then compose full ticks only after the weapon body returns with recovered effects.
|
| 43 |
+
7. Validate finite fixtures against original execution and collision-consistent traces, including legal command/state transitions and event-ring pressure.
|
| 44 |
+
8. Map numeric animation and event IDs to actual skeletal/audio assets, preserving variants and provenance.
|
| 45 |
+
9. Continue native/DLL/network/protocol/rendering/material and whole-content coverage from the broader todo-list.
|
| 46 |
+
10. Establish the first Rust/Bevy/Solari runtime slice and macOS/Linux validation; these bounded research tasks do not count as a playable game or platform completion.
|
docs/research/QVM_MAIN_CONSUMERS.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Main request and independently bounded animation consumer chains
|
| 2 |
+
|
| 3 |
+
RE-569. Reproduce with `python3 scripts/analyze_qvm_main_consumers.py`; check with `python3 scripts/test_qvm_main_consumers.py`. The [machine report](qvm-main-consumers.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Two actual main instruction segments now compose recovered consumers.54444..54451 calls49652 with argument1 then49918; its resulting state feeds inspection of the pending50746 call only through the recovered prefix. The parent stops before54452 and is never resumed after the partial child. Accepted reload replaces PS44, blocks the following interaction via its positive timer, then the weapon prefix subtracts the tick dt.24 fixtures include conflicting buttons, state128 direct-action conditions, supplied trace misses/hits and edge events.
|
| 6 |
+
|
| 7 |
+
Separately,54455..54463 calls49117 torso,47884 locomotion and48716 water events using explicitly supplied post-weapon state.18 fixtures check exact ordered handoffs, grounded/airborne command differences, locomotion overriding a prior torso choice when helper guards permit, and movement events preceding water events in the two-slot ring. These fixtures do not inherit the partial weapon prefix state or imply that the missing weapon body has no effect.
|
| 8 |
+
|
| 9 |
+
The source gap50872..53045 remains unrecovered; final vector-snap native request54471 and the main prefix/environment/movement are outside this task. A complete main tick cannot yet be claimed. See the [ten-task batch and concrete next work](QVM_CONSUMER_BATCH.md). RE-570 tracks weapon completion, availability/resource writers, final main effects, original reference validation and full Rust/Bevy/Solari platform implementation.
|
| 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
|
@@ -310,3 +310,8 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 310 |
|
| 311 |
|
| 312 |
[RE-568: Complete locomotion gait bob and footstep consumer](QVM_LOCOMOTION.md). Reproduce with `python3 scripts/analyze_qvm_locomotion.py`; check with `python3 scripts/test_qvm_locomotion.py`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 310 |
|
| 311 |
|
| 312 |
[RE-568: Complete locomotion gait bob and footstep consumer](QVM_LOCOMOTION.md). Reproduce with `python3 scripts/analyze_qvm_locomotion.py`; check with `python3 scripts/test_qvm_locomotion.py`.
|
| 313 |
+
|
| 314 |
+
[RE-560–569 consumer batch and next work](QVM_CONSUMER_BATCH.md): ten separate task commits, bounded coverage and explicit missing weapon/main runtime scope.
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
[RE-569: Main request and independently bounded animation consumer chains](QVM_MAIN_CONSUMERS.md). Reproduce with `python3 scripts/analyze_qvm_main_consumers.py`; check with `python3 scripts/test_qvm_main_consumers.py`.
|
docs/research/qvm-main-consumers.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_main_consumers.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Two actual main suffix segments separated by unrecovered weapon continuation."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source,execute
|
| 6 |
+
from qvm_suffix_support import seed,state,weapon_config
|
| 7 |
+
from analyze_qvm_reload_request import reload
|
| 8 |
+
from analyze_qvm_interaction_request import interaction
|
| 9 |
+
from analyze_qvm_weapon_prefix import weapon_prefix
|
| 10 |
+
from analyze_qvm_torso_selector import torso
|
| 11 |
+
from analyze_qvm_locomotion import locomotion
|
| 12 |
+
from analyze_qvm_water_events import water_events
|
| 13 |
+
from analyze_qvm_acceleration import PS,FRAME
|
| 14 |
+
from analyze_qvm import write_json
|
| 15 |
+
LOCAL=0x72000000
|
| 16 |
+
|
| 17 |
+
def entry_chain(ins,m,contents,cmd=(0,0,0)):
|
| 18 |
+
initial=state(m)
|
| 19 |
+
def reload_child(i,m,a,c):m,r=reload(i,m,a[8],c);return m,c,0,r
|
| 20 |
+
def interaction_child(i,m,a,c):m,r=interaction(i,m,contents,c);return m,c,0,r
|
| 21 |
+
m,c,r=execute(ins,54444,54452,m,cmd,LOCAL,{49652:reload_child,49918:interaction_child});before=state(m)
|
| 22 |
+
assert ins[54452]['operand']==50746 and ins[54453]['opcode']=='CALL'
|
| 23 |
+
m,w=weapon_prefix(ins,m,c)
|
| 24 |
+
return {'initial':initial,'main_execution':r,'before_weapon':before,'weapon_prefix':w,'final':state(m),'main_stopped_before':54452,'pending_call_instruction':54453,'parent_resumed':False}
|
| 25 |
+
|
| 26 |
+
def animation_chain(ins,m,cmd):
|
| 27 |
+
initial=state(m)
|
| 28 |
+
def child(fn):
|
| 29 |
+
def apply(i,m,a,c):m,r=fn(i,m,c);return m,c,0,r
|
| 30 |
+
return apply
|
| 31 |
+
m,c,r=execute(ins,54455,54464,m,cmd,LOCAL+0x1000,{49117:child(torso),47884:child(locomotion),48716:child(water_events)})
|
| 32 |
+
return {'initial':initial,'supplied_post_weapon_state':True,'execution':r,'final':state(m),'stop_before':54464}
|
| 33 |
+
|
| 34 |
+
def main():
|
| 35 |
+
q,raw,h,ins=source();entries=[];animations=[]
|
| 36 |
+
for buttons,flags,contents in itertools.product([0,32,64,96,136,224],[0,128],[0,33554432]):
|
| 37 |
+
m=weapon_config(seed(raw,h),raw,h);m.update({FRAME+20:buttons,PS+220:flags,PS+312:22|(2<<8)|(3<<24),PS+44:0,PS+376:19,PS+188:1000,PS+196:15});entries.append(entry_chain(ins,m,contents))
|
| 38 |
+
for cmd,ground,levels in itertools.product([(0,0,0),(127,0,0),(101,0,0)],[8,1023],[(0,3),(3,0),(0,1)]):
|
| 39 |
+
m=weapon_config(seed(raw,h,cmd),raw,h);m.update({PS+312:22,PS+44:0,PS+68:ground,PS+12:8 if ground==1023 else 0,PS+8:60,35024028:levels[0],FRAME+212:levels[1],FRAME+20:0});animations.append(animation_chain(ins,m,cmd))
|
| 40 |
+
write_json(Path('docs/research/qvm-main-consumers.json'),{'source':q['source'],'sha256':q['sha256'],'entry_chains':entries,'animation_chains':animations,'limits':'Two separate bounded main segments, NOT a complete tick.54444..54451 reload/interaction then inspect50746 prefix without resuming suspended parent.54455..54463 torso/locomotion/water uses independently supplied post-weapon state. No transfer across missing weapon continuation50872..53045; final native vector snap54471 and main prefix/environment/movement omitted.'})
|
| 41 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_main_consumers.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest,copy
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_reload_request import allowed
|
| 4 |
+
from test_qvm_interaction_request import route
|
| 5 |
+
from test_qvm_weapon_prefix import mode_state
|
| 6 |
+
from test_qvm_packed_controls import resource_state,i32
|
| 7 |
+
from test_qvm_torso_selector import request,signed
|
| 8 |
+
from test_qvm_locomotion import locomotion_state
|
| 9 |
+
from test_qvm_water_events import expected,enqueue
|
| 10 |
+
|
| 11 |
+
def reload_state(p):
|
| 12 |
+
a=copy.deepcopy(p['initial'])
|
| 13 |
+
if allowed(p):
|
| 14 |
+
cfg=p['config'];a['state220']|=8;a['weapon_timer']=(cfg['reload']+(cfg['reload_extra'] if p['argument'] else 0))&0xffffffff;a['torso_timer']=p['supplied_animation_duration']&0xffffffff
|
| 15 |
+
if p['kind']<3:a['torso']=((a['torso']&128)^128)|(57 if cfg['class']>=4 else 56)
|
| 16 |
+
a['queue']=enqueue(a['queue'],[3])
|
| 17 |
+
return a
|
| 18 |
+
|
| 19 |
+
def interaction_state(p):
|
| 20 |
+
a=copy.deepcopy(p['initial']);r=route(p)
|
| 21 |
+
if r in ['hit','direct']:
|
| 22 |
+
a['state220']=(a['state220']|1) if r=='hit' else (a['state220']|512)&~8;a['weapon_timer']=(750 if a['health']>0 and any(x&255==19 for x in a['inventory']) else 1500) if r=='hit' else 1000;a['torso_timer']=321
|
| 23 |
+
if p['kind']<3:a['torso']=((a['torso']&128)^128)|46
|
| 24 |
+
a['queue']=enqueue(a['queue'],[12 if r=='hit' else 4])
|
| 25 |
+
return a
|
| 26 |
+
|
| 27 |
+
def weapon_state(p):
|
| 28 |
+
a=copy.deepcopy(p['initial']);buttons=p['buttons']
|
| 29 |
+
if not buttons&1:a['state220']&=~32
|
| 30 |
+
if not a['flags']&256 and signed(a['health'])>0:
|
| 31 |
+
edge,resource,mode=[x['effect'] for x in p['execution']['children']];pressed=bool(buttons&128);event=pressed and not a['state220']&32768;a['state220']=(a['state220']|32768) if pressed else a['state220']&~32768;a['queue']=enqueue(a['queue'],[15] if event else [])
|
| 32 |
+
if signed(a['weapon_timer'])>0:a['weapon_timer']=i32(signed(a['weapon_timer'])-p['dt'])&0xffffffff
|
| 33 |
+
assert a==resource['initial'];a=resource_state(resource);assert a==mode['initial'];a=mode_state(mode)
|
| 34 |
+
return a
|
| 35 |
+
class MainConsumersTests(unittest.TestCase):
|
| 36 |
+
@classmethod
|
| 37 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-main-consumers.json').read_text())
|
| 38 |
+
def test_actual_main_reload_interaction_and_weapon_entry_handoffs(self):
|
| 39 |
+
self.assertEqual(len(self.r['entry_chains']),24)
|
| 40 |
+
for p in self.r['entry_chains']:
|
| 41 |
+
self.assertEqual([c['target'] for c in p['main_execution']['calls']],[49652,49918]);reload,interaction=[x['effect'] for x in p['main_execution']['children']];self.assertEqual(reload['argument'],1);self.assertEqual(reload['initial'],p['initial']);self.assertEqual(reload['final'],reload_state(reload));self.assertEqual(interaction['initial'],reload['final']);self.assertEqual(interaction['final'],interaction_state(interaction));self.assertEqual(p['before_weapon'],interaction['final']);self.assertEqual(p['weapon_prefix']['initial'],p['before_weapon']);self.assertEqual(p['final'],weapon_state(p['weapon_prefix']))
|
| 42 |
+
def test_reload_timer_blocks_following_interaction_then_decrements(self):
|
| 43 |
+
rows=[p for p in self.r['entry_chains'] if p['main_execution']['children'][0]['effect']['buttons']&96==96];self.assertTrue(rows)
|
| 44 |
+
for p in rows:
|
| 45 |
+
reload,interaction=[x['effect'] for x in p['main_execution']['children']];self.assertTrue(allowed(reload));self.assertEqual(route(interaction),'blocked');self.assertEqual(p['final']['weapon_timer'],reload['final']['weapon_timer']-p['weapon_prefix']['dt'])
|
| 46 |
+
def test_independent_animation_tail_source_order_exact_state(self):
|
| 47 |
+
self.assertEqual(len(self.r['animation_chains']),18)
|
| 48 |
+
for p in self.r['animation_chains']:
|
| 49 |
+
self.assertEqual([c['target'] for c in p['execution']['calls']],[49117,47884,48716]);torso,locomotion,water=[x['effect'] for x in p['execution']['children']];a=copy.deepcopy(p['initial']);self.assertEqual(torso['initial'],a);r=request(torso)
|
| 50 |
+
if r is not None and signed(a['torso_timer'])<=0 and a['torso']&~128!=r:a['torso']=((a['torso']&128)^128)|r
|
| 51 |
+
self.assertEqual(torso['final'],a);self.assertEqual(locomotion['initial'],a);a=locomotion_state(locomotion)[0];self.assertEqual(locomotion['final'],a);self.assertEqual(water['initial'],a);a['queue']=enqueue(a['queue'],expected(water));self.assertEqual(p['final'],a)
|
| 52 |
+
def test_missing_weapon_gap_never_resumes_parent_or_claims_full_tick(self):
|
| 53 |
+
self.assertIn('NOT a complete tick',self.r['limits'])
|
| 54 |
+
for p in self.r['entry_chains']:self.assertFalse(p['parent_resumed']);self.assertEqual(p['main_stopped_before'],54452);self.assertEqual(p['pending_call_instruction'],54453);self.assertIn(p['weapon_prefix']['execution']['stop'],[50872,53046])
|
| 55 |
+
for p in self.r['animation_chains']:self.assertTrue(p['supplied_post_weapon_state']);self.assertEqual(p['stop_before'],54464)
|
| 56 |
+
if __name__=='__main__':unittest.main()
|