qvm: complete bounded walking
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +3 -0
- docs/PROVISIONAL_TODO.md +3 -0
- docs/RESEARCH_LEDGER.md +9 -0
- docs/REVERSE_ENGINEERING_TODO.md +6 -0
- docs/research/QVM_MOVEMENT_BATCH.md +13 -10
- docs/research/QVM_WALKING_MODE.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-walking-mode.json +0 -0
- scripts/analyze_qvm_walk_entry.py +7 -2
- scripts/analyze_qvm_walking_mode.py +58 -0
- scripts/test_qvm_direction_codec.py +3 -0
- scripts/test_qvm_move_direction.py +3 -0
- scripts/test_qvm_swim_mode.py +3 -0
- scripts/test_qvm_walk_policy.py +3 -0
- scripts/test_qvm_walk_wish.py +3 -0
- scripts/test_qvm_walking_mode.py +57 -0
- scripts/test_qvm_wall_action.py +3 -0
- scripts/test_qvm_wall_probe.py +3 -0
- scripts/test_qvm_water_entry.py +3 -0
- scripts/test_qvm_water_route.py +3 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -367,3 +367,6 @@ Research progress: RE-556 [report](research/QVM_WALK_WISH.md); remaining native/
|
|
| 367 |
|
| 368 |
|
| 369 |
Research progress: RE-557 [report](research/QVM_WALK_POLICY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
|
| 368 |
|
| 369 |
Research progress: RE-557 [report](research/QVM_WALK_POLICY.md); remaining native/content/runtime/platform scope stays open.
|
| 370 |
+
|
| 371 |
+
|
| 372 |
+
Research progress: RE-558 [report](research/QVM_WALKING_MODE.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -725,3 +725,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 725 |
|
| 726 |
|
| 727 |
**RE-557 — Recover walking speed policy acceleration projection and resource:** Walking applies flag/state/resource/water caps then a timed state128 override, selects acceleration from surface/flags/speed, performs two normalized plane projections and passes saved pre-projection speed into39595. [Evidence](research/QVM_WALK_POLICY.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 725 |
|
| 726 |
|
| 727 |
**RE-557 — Recover walking speed policy acceleration projection and resource:** Walking applies flag/state/resource/water caps then a timed state128 override, selects acceleration from surface/flags/speed, performs two normalized plane projections and passes saved pre-projection speed into39595. [Evidence](research/QVM_WALK_POLICY.md).
|
| 728 |
+
|
| 729 |
+
|
| 730 |
+
**RE-558 — Complete bounded walking wrapper and combined main handoffs:** Complete43626 routes actual entry to air/water or normal policy, clears32 and runs60091(0) only when horizontal velocity is nonzero; actual main posture/contents/ground/timer/action/query and post-ground share the resulting state. [Evidence](research/QVM_WALKING_MODE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -679,3 +679,6 @@ Research progress: RE-556 [report](research/QVM_WALK_WISH.md); remaining native/
|
|
| 679 |
|
| 680 |
|
| 681 |
Research progress: RE-557 [report](research/QVM_WALK_POLICY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 679 |
|
| 680 |
|
| 681 |
Research progress: RE-557 [report](research/QVM_WALK_POLICY.md); remaining native/content/runtime/platform scope stays open.
|
| 682 |
+
|
| 683 |
+
|
| 684 |
+
Research progress: RE-558 [report](research/QVM_WALKING_MODE.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -487,3 +487,12 @@ Walking friction and copied-command scaling precede actual40679, flattening and
|
|
| 487 |
## 2026-10-19 — RE-557 Recover walking speed policy acceleration projection and resource (separate task commit)
|
| 488 |
|
| 489 |
Walking applies flag/state/resource/water caps then a timed state128 override, selects acceleration from surface/flags/speed, performs two normalized plane projections and passes saved pre-projection speed into39595. 30 command/policy profiles and four independent tests reproduce exact speed/cap/coefficient rounding, acceleration, both projections, timed250 boundary and resource outputs. Full suite: 755 tests pass. Report regenerates byte-identically (416388 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
## 2026-10-19 — RE-557 Recover walking speed policy acceleration projection and resource (separate task commit)
|
| 488 |
|
| 489 |
Walking applies flag/state/resource/water caps then a timed state128 override, selects acceleration from surface/flags/speed, performs two normalized plane projections and passes saved pre-projection speed into39595. 30 command/policy profiles and four independent tests reproduce exact speed/cap/coefficient rounding, acceleration, both projections, timed250 boundary and resource outputs. Full suite: 755 tests pass. Report regenerates byte-identically (416388 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 490 |
+
|
| 491 |
+
|
| 492 |
+
## 2026-10-19 — RE-558 Complete bounded walking wrapper and combined main handoffs (separate task commit)
|
| 493 |
+
|
| 494 |
+
Complete43626 routes actual entry to air/water or normal policy, clears32 and runs60091(0) only when horizontal velocity is nonzero; actual main posture/contents/ground/timer/action/query and post-ground share the resulting state. 26 standalone/8 combined-main fixtures and four independent tests compose all prior child oracles, native-supplied wrapper/step paths, zero-horizontal controls, entry events/resource and higher-priority mode suppression. All ten direct test entrypoints are executable. Full suite: 759 tests pass. Report regenerates byte-identically (1716605 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 495 |
+
|
| 496 |
+
### Ten-task batch final regression audit
|
| 497 |
+
|
| 498 |
+
RE-549–558 each has its own code/tests/report/documentation commit. All759 tests pass; all ten direct test commands execute four tests each. Ten new reports and six prior contact/main/active/flagged/walk-entry/air reports regenerate byte-identically after final integration. New reports remain below the2MiB normal-Git cap. Completed coverage and explicit native-supplied limits are indexed in `research/QVM_MOVEMENT_BATCH.md`; RE-559 preserves remaining original-reference/native/runtime/rendering/content/platform work. No asset payloads or Rust runtime were added.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -716,3 +716,9 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 716 |
|
| 717 |
|
| 718 |
- [x] RE-557 Recover walking speed policy acceleration projection and resource ([report](research/QVM_WALK_POLICY.md)).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 716 |
|
| 717 |
|
| 718 |
- [x] RE-557 Recover walking speed policy acceleration projection and resource ([report](research/QVM_WALK_POLICY.md)).
|
| 719 |
+
|
| 720 |
+
|
| 721 |
+
- [ ] RE-559 Validate these movement paths against original execution and collision-consistent native traces; complete remaining main prefix/suffix/scheduler/event-resource-animation consumers, full cross-module rules/network/audio/rendering/assets coverage and Rust/Bevy/Solari macOS/Linux platform prototype and runtime. See the [ten-task batch](research/QVM_MOVEMENT_BATCH.md) for bounded completed coverage.
|
| 722 |
+
|
| 723 |
+
|
| 724 |
+
- [x] RE-558 Complete bounded walking wrapper and combined main handoffs ([report](research/QVM_WALKING_MODE.md)).
|
docs/research/QVM_MOVEMENT_BATCH.md
CHANGED
|
@@ -4,15 +4,18 @@ Each task has its own tested code/report/documentation commit. Completed rows li
|
|
| 4 |
|
| 5 |
| Task | Completion scope |
|
| 6 |
| --- | --- |
|
| 7 |
-
| RE-549 | Complete40679 direction classifier and idle transitions. |
|
| 8 |
-
| RE-550 | File-backed162-direction encode/decode services and tie/index rules. |
|
| 9 |
-
| RE-551 | Wall-contact42838 guards, trace geometry, hull restoration and failure state. |
|
| 10 |
-
| RE-552 | Wall success40966/event86/animation and ordinary-air continuation. |
|
| 11 |
-
| RE-553 | Complete41486 water-entry query and launch state. |
|
| 12 |
-
| RE-554 | Actual41848 water-entry guard and41768 fallback routing. |
|
| 13 |
-
| RE-555 | Remaining41848 swim wish/acceleration/clip/slide body. |
|
| 14 |
-
| RE-556 | Walking43626 ordinary direction/basis/wish producer. |
|
| 15 |
-
| RE-557 | Walking acceleration, slope velocity and resource suffix. |
|
| 16 |
-
| RE-558 | Complete bounded walking wrapper and actual main/environment handoffs. |
|
| 17 |
|
| 18 |
Native roots, trace/content records and initial finite state remain supplied until actual native behavior is established. These tasks add research fixtures, not a Rust/Bevy/Solari runtime or platform proof. The wall/swim/walk scopes may expose additional required callees; those dependencies are recovered or explicitly recorded within the corresponding task before it is marked complete.
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
| Task | Completion scope |
|
| 6 |
| --- | --- |
|
| 7 |
+
| [RE-549](QVM_MOVE_DIRECTION.md) ✓ | Complete40679 direction classifier and idle transitions. |
|
| 8 |
+
| [RE-550](QVM_DIRECTION_CODEC.md) ✓ | File-backed162-direction encode/decode services and tie/index rules. |
|
| 9 |
+
| [RE-551](QVM_WALL_PROBE.md) ✓ | Wall-contact42838 guards, trace geometry, hull restoration and failure state. |
|
| 10 |
+
| [RE-552](QVM_WALL_ACTION.md) ✓ | Wall success40966/event86/animation and ordinary-air continuation. |
|
| 11 |
+
| [RE-553](QVM_WATER_ENTRY.md) ✓ | Complete41486 water-entry query and launch state. |
|
| 12 |
+
| [RE-554](QVM_WATER_ROUTE.md) ✓ | Actual41848 water-entry guard and41768 fallback routing. |
|
| 13 |
+
| [RE-555](QVM_SWIM_MODE.md) ✓ | Remaining41848 swim wish/acceleration/clip/slide body. |
|
| 14 |
+
| [RE-556](QVM_WALK_WISH.md) ✓ | Walking43626 ordinary direction/basis/wish producer. |
|
| 15 |
+
| [RE-557](QVM_WALK_POLICY.md) ✓ | Walking acceleration, slope velocity and resource suffix. |
|
| 16 |
+
| [RE-558](QVM_WALKING_MODE.md) ✓ | Complete bounded walking wrapper and actual main/environment handoffs. |
|
| 17 |
|
| 18 |
Native roots, trace/content records and initial finite state remain supplied until actual native behavior is established. These tasks add research fixtures, not a Rust/Bevy/Solari runtime or platform proof. The wall/swim/walk scopes may expose additional required callees; those dependencies are recovered or explicitly recorded within the corresponding task before it is marked complete.
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
All ten tasks are complete as separately tested commits. Each report labels finite/native-supplied inputs and remaining runtime limits. The final batch verifies all direct test entrypoints, full-suite checks and byte-identical regeneration of existing reports. RE-559 tracks follow-up reference/native/renderer/runtime and remaining scheduler/consumer work.
|
docs/research/QVM_WALKING_MODE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Complete bounded walking wrapper and combined main handoffs
|
| 2 |
+
|
| 3 |
+
RE-558. Reproduce with `python3 scripts/analyze_qvm_walking_mode.py`; check with `python3 scripts/test_qvm_walking_mode.py`. The [machine report](qvm-walking-mode.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Normal walking now continues after the resource update into source horizontal-zero routing and the real gravity-off60091 wrapper, including conditional step/second-slide/fallback. A vertical-only control confirms the skip checks X/Y, not full speed. Successful40966 delegation uses actual ordinary air or41848 water body/fallback; normal walking uses the recovered speed/resource policy. Eight main fixtures combine actual posture, contents, ground, timer, action, query, selected movement and post-environment. Flat-ground source processing can clear128 before dispatch; retained128 controls use supplied steep-ground responses and select41768, suppressing walking effects. Native trace/content/root inputs remain supplied and legal consistency is unverified. The task also validates batch test CLI entrypoints and preserves earlier default report formats. Whole-game runtime, reference execution, native collision correctness, main prefix/suffix consumers, networking/rendering/assets and macOS/Linux Rust/Bevy/Solari implementation remain open.
|
| 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
|
@@ -280,3 +280,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 280 |
|
| 281 |
|
| 282 |
[RE-557: Recover walking speed policy acceleration projection and resource](QVM_WALK_POLICY.md). Reproduce with `python3 scripts/analyze_qvm_walk_policy.py`; check with `python3 scripts/test_qvm_walk_policy.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
|
| 281 |
|
| 282 |
[RE-557: Recover walking speed policy acceleration projection and resource](QVM_WALK_POLICY.md). Reproduce with `python3 scripts/analyze_qvm_walk_policy.py`; check with `python3 scripts/test_qvm_walk_policy.py`.
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
[RE-558: Complete bounded walking wrapper and combined main handoffs](QVM_WALKING_MODE.md). Reproduce with `python3 scripts/analyze_qvm_walking_mode.py`; check with `python3 scripts/test_qvm_walking_mode.py`.
|
docs/research/qvm-walking-mode.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_walk_entry.py
CHANGED
|
@@ -18,7 +18,7 @@ from analyze_vm_extensions import verified
|
|
| 18 |
LOCAL=0x62000000
|
| 19 |
|
| 20 |
|
| 21 |
-
def route(ins,m,cmd,air_effect=None):
|
| 22 |
initial=snapshot(m);level=m[FRAME+212];basis=[m[35023892+4*i]&0xffffffff for i in range(3)];normal=[m[35023968+4*i]&0xffffffff for i in range(3)];pc=43627;trace=[];calls=[];launch=None;air=None
|
| 23 |
while True:
|
| 24 |
t=trace_slice(ins,43627,45199,m,{},resume_at=pc,stop_targets=[s for s in [43662,43683] if s!=pc],local_base=LOCAL,call_results={43660:0},limit=1024);m=t['memory'];trace+=t['trace'];calls+=t['calls'];pc=t['stop']
|
|
@@ -26,7 +26,12 @@ def route(ins,m,cmd,air_effect=None):
|
|
| 26 |
else:break
|
| 27 |
delegated=[c['target'] for c in calls if c['target'] in [41848,42838]];target=delegated[0] if delegated else None
|
| 28 |
if target==42838 and air_effect:m,air=air_effect(ins,m,cmd)
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
|
| 32 |
def main_case(ins,constants,up,flags,air_effect=None,meter=4000):
|
|
|
|
| 18 |
LOCAL=0x62000000
|
| 19 |
|
| 20 |
|
| 21 |
+
def route(ins,m,cmd,air_effect=None,water_effect=None):
|
| 22 |
initial=snapshot(m);level=m[FRAME+212];basis=[m[35023892+4*i]&0xffffffff for i in range(3)];normal=[m[35023968+4*i]&0xffffffff for i in range(3)];pc=43627;trace=[];calls=[];launch=None;air=None
|
| 23 |
while True:
|
| 24 |
t=trace_slice(ins,43627,45199,m,{},resume_at=pc,stop_targets=[s for s in [43662,43683] if s!=pc],local_base=LOCAL,call_results={43660:0},limit=1024);m=t['memory'];trace+=t['trace'];calls+=t['calls'];pc=t['stop']
|
|
|
|
| 26 |
else:break
|
| 27 |
delegated=[c['target'] for c in calls if c['target'] in [41848,42838]];target=delegated[0] if delegated else None
|
| 28 |
if target==42838 and air_effect:m,air=air_effect(ins,m,cmd)
|
| 29 |
+
water=None
|
| 30 |
+
if target==41848 and water_effect:m,water=water_effect(ins,m,cmd)
|
| 31 |
+
report={'initial':initial,'level':level,'basis':basis,'normal':normal,'commands':list(cmd),'entry':launch,'delegated_target':target,'stop_instruction':pc,'air':air,'final':snapshot(m),'calls':calls,**trace_fields({'trace':trace},False)}
|
| 32 |
+
|
| 33 |
+
if water_effect:report['water']=water
|
| 34 |
+
return m,report
|
| 35 |
|
| 36 |
|
| 37 |
def main_case(ins,constants,up,flags,air_effect=None,meter=4000):
|
scripts/analyze_qvm_walking_mode.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Full finite43626 routing/ordinary policy/wrapper and actual combined main."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source,memory,constants,execute
|
| 6 |
+
from analyze_qvm_walk_policy import policy,CONFIG
|
| 7 |
+
from analyze_qvm_walk_wish import LOCAL
|
| 8 |
+
from analyze_qvm_walk_entry import route
|
| 9 |
+
from analyze_qvm_air_mode import air
|
| 10 |
+
from analyze_qvm_swim_mode import swim
|
| 11 |
+
from analyze_qvm_contact_callers import wrapper
|
| 12 |
+
from analyze_qvm_acceleration import PS,FRAME,word
|
| 13 |
+
from analyze_qvm_jump_entry import snapshot
|
| 14 |
+
from analyze_qvm_main_contact import probe
|
| 15 |
+
from analyze_qvm_main_environment import contents
|
| 16 |
+
from analyze_qvm_combined_ground import ground_all
|
| 17 |
+
from analyze_qvm_main_posture import posture
|
| 18 |
+
from analyze_qvm_action_probe import action,PATTERNS
|
| 19 |
+
from analyze_qvm_main_query import coupled
|
| 20 |
+
from analyze_qvm import write_json
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def walking(ins,m,cmd,pattern='clear'):
|
| 24 |
+
def airborne(i,m,c):return air(i,m,c,pattern)
|
| 25 |
+
def water(i,m,c):return swim(i,m,c,(1,0) if c[2]>=10 else (0,0),pattern)
|
| 26 |
+
m,p=route(ins,m,cmd,airborne,water);normal=None;w=None;tail=None
|
| 27 |
+
if p['stop_instruction']==43683:
|
| 28 |
+
cmd=p['commands'];m,normal=policy(ins,m,cmd)
|
| 29 |
+
def move(i,m,a,c):
|
| 30 |
+
nonlocal w
|
| 31 |
+
m,w=wrapper(i,m,pattern,'clear','clear',a[8]);return m,c,w['return_word'],{}
|
| 32 |
+
m,cmd,tail=execute(ins,45143,45199,m,cmd,LOCAL,{60091:move})
|
| 33 |
+
return m,{'route':p,'policy':normal,'wrapper':w,'tail':tail,'final':snapshot(m)}
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def main():
|
| 37 |
+
q,raw,h,ins=source();cfg=constants(raw,h,CONFIG+[21196]);rows=[]
|
| 38 |
+
for cmd,level,pattern in itertools.product([(0,0,0),(100,0,0),(-128,127,0),(100,0,10)],[0,2,3],['clear','contacts']):
|
| 39 |
+
m=memory(raw,h,cmd);m.update(cfg);m[PS+220]=0;m[FRAME+212]=level;rows.append(walking(ins,m,cmd,pattern)[1])
|
| 40 |
+
for z in [0,1]:
|
| 41 |
+
m=memory(raw,h,(0,0,0),flags=32);m.update(cfg);m[PS+220]=0
|
| 42 |
+
for j,v in enumerate([0,0,z]):m[PS+32+4*j]=word(v)
|
| 43 |
+
for j,v in enumerate([0,0,1]):m[35023968+4*j]=word(v)
|
| 44 |
+
rows.append(walking(ins,m,(0,0,0))[1])
|
| 45 |
+
chains=[]
|
| 46 |
+
for up,flags,pattern in itertools.product([0,10],[32,160],['clear','contacts']):
|
| 47 |
+
cmd=(100,0,up);m=memory(raw,h,cmd,flags=flags);m.update(cfg);m.update({PS+220:0,PS+184:8000,PS+376:17})
|
| 48 |
+
def env(i,m,target,phase):
|
| 49 |
+
m,r=contents(i,m,[0,0,0]) if target==47217 else ground_all(i,m,'flat' if flags==32 else 'steep');r['phase']=phase;return m,r
|
| 50 |
+
def post(i,m):return posture(i,m,up,0)
|
| 51 |
+
def act(i,m):return action(i,m,0,PATTERNS['none'])
|
| 52 |
+
def query(i,m):return coupled(i,m,{'forward':100,'fractions':(1,1)})
|
| 53 |
+
def mode(i,m):return walking(i,m,cmd,pattern)
|
| 54 |
+
p=probe(ins,1016,0,flags,'clear',initial_memory=m,environment_effect=env,posture_effect=post,action_effect=act,query_effect=query,walking_mode_effect=mode);p.update({'commands':list(cmd),'input_flags':flags});chains.append(p)
|
| 55 |
+
write_json(Path('docs/research/qvm-walking-mode.json'),{'source':q['source'],'sha256':q['sha256'],'constants':{str(a):v for a,v in cfg.items()},'probes':rows,'main_chains':chains,'limits':'Full bounded43626 entry/ordinary/water-air delegation with recovered children; actual main posture/content/ground/timer/action/query/walking and post-environment share memory. Native roots/contents/stand/ground/slide/step traces supplied, not collision-derived. No original executable/full QVM/native physics/rendering executes. Remaining wall-specific main integration, other main prefix/suffix/consumers/native legal domains/reference execution/full Rust/Bevy/Solari platforms remain open.'})
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_direction_codec.py
CHANGED
|
@@ -27,3 +27,6 @@ class DirectionCodecTests(unittest.TestCase):
|
|
| 27 |
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());raw=Path(q['source']['member']['output']).read_bytes();h,_=decode(raw);self.assertEqual(self.r['sha256'],hashlib.sha256(raw).hexdigest())
|
| 28 |
for i,v in enumerate(self.r['table']):
|
| 29 |
for j,w in enumerate(v):self.assertEqual(int.from_bytes(raw[h['data_offset']+21732+12*i+4*j:h['data_offset']+21736+12*i+4*j],'little'),w)
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());raw=Path(q['source']['member']['output']).read_bytes();h,_=decode(raw);self.assertEqual(self.r['sha256'],hashlib.sha256(raw).hexdigest())
|
| 28 |
for i,v in enumerate(self.r['table']):
|
| 29 |
for j,w in enumerate(v):self.assertEqual(int.from_bytes(raw[h['data_offset']+21732+12*i+4*j:h['data_offset']+21736+12*i+4*j],'little'),w)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_move_direction.py
CHANGED
|
@@ -20,3 +20,6 @@ class MoveDirectionTests(unittest.TestCase):
|
|
| 20 |
for p in self.r['probes']:self.assertEqual(p['calls'],[]);self.assertEqual(p['canary'],123)
|
| 21 |
def test_source_partition_identity(self):
|
| 22 |
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());self.assertEqual(self.r['sha256'],hashlib.sha256(Path(q['source']['member']['output']).read_bytes()).hexdigest());self.assertEqual(self.r['instructions'][0]['index'],40679);self.assertEqual(self.r['instructions'][-1]['index'],40965)
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
for p in self.r['probes']:self.assertEqual(p['calls'],[]);self.assertEqual(p['canary'],123)
|
| 21 |
def test_source_partition_identity(self):
|
| 22 |
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());self.assertEqual(self.r['sha256'],hashlib.sha256(Path(q['source']['member']['output']).read_bytes()).hexdigest());self.assertEqual(self.r['instructions'][0]['index'],40679);self.assertEqual(self.r['instructions'][-1]['index'],40965)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_swim_mode.py
CHANGED
|
@@ -40,3 +40,6 @@ class SwimTests(unittest.TestCase):
|
|
| 40 |
self.assertEqual(sum(m['water_mode']['body'] is None for m in self.r['main_chains']),2)
|
| 41 |
for m in self.r['main_chains']:
|
| 42 |
p=m['water_mode'];self.assertEqual(p['body'] is None,p['prefix']['fallback'] is not None)
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
self.assertEqual(sum(m['water_mode']['body'] is None for m in self.r['main_chains']),2)
|
| 41 |
for m in self.r['main_chains']:
|
| 42 |
p=m['water_mode'];self.assertEqual(p['body'] is None,p['prefix']['fallback'] is not None)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_walk_policy.py
CHANGED
|
@@ -46,3 +46,6 @@ class WalkPolicyTests(unittest.TestCase):
|
|
| 46 |
def test_surface_or_flag_selects_gravity_and_low_accel(self):
|
| 47 |
rows=[p for p in self.r['probes'] if p['inputs']['surface']&2 or p['inputs']['flags']&64];self.assertEqual(len(rows),6)
|
| 48 |
for p in rows:self.assertEqual(p['acceleration']['acceleration_float_word'],speed(p,self.c)[1])
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
def test_surface_or_flag_selects_gravity_and_low_accel(self):
|
| 47 |
rows=[p for p in self.r['probes'] if p['inputs']['surface']&2 or p['inputs']['flags']&64];self.assertEqual(len(rows),6)
|
| 48 |
for p in rows:self.assertEqual(p['acceleration']['acceleration_float_word'],speed(p,self.c)[1])
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_walk_wish.py
CHANGED
|
@@ -31,3 +31,6 @@ class WalkWishTests(unittest.TestCase):
|
|
| 31 |
flat=n(p['normal'][2])==1;self.assertEqual(all(n(v[2])==0 for v in p['basis_after']),flat)
|
| 32 |
def test_idle_old2_and6_feed_real_direction_child(self):
|
| 33 |
idle=[p for p in self.r['probes'] if p['scale']['movement_bytes']==[0,0,0]];self.assertEqual({p['direction']['after'] for p in idle},{1,7})
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
flat=n(p['normal'][2])==1;self.assertEqual(all(n(v[2])==0 for v in p['basis_after']),flat)
|
| 32 |
def test_idle_old2_and6_feed_real_direction_child(self):
|
| 33 |
idle=[p for p in self.r['probes'] if p['scale']['movement_bytes']==[0,0,0]];self.assertEqual({p['direction']['after'] for p in idle},{1,7})
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_walking_mode.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy,json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import f,n,word
|
| 4 |
+
from test_qvm_walk_policy import check as check_policy
|
| 5 |
+
from test_qvm_air_mode import check as check_air
|
| 6 |
+
from test_qvm_swim_mode import check as check_swim
|
| 7 |
+
from test_qvm_water_route import check_wrapper
|
| 8 |
+
from test_qvm_jump_entry import check as check_entry
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def check(test,p,c):
|
| 12 |
+
route=p['route']
|
| 13 |
+
if route['entry']:check_entry(test,route['entry'])
|
| 14 |
+
if p['policy']:
|
| 15 |
+
check_policy(test,p['policy'],c);s=copy.deepcopy(p['policy']['final']);s['flags']&=~32
|
| 16 |
+
if p['wrapper']:
|
| 17 |
+
w=p['wrapper'];check_wrapper(test,w,p['policy']['wish']['normal']);test.assertEqual(w['before']['velocity'],s['velocity']);test.assertEqual(w['before']['flags'],s['flags']);test.assertEqual(w['first_slide']['gravity'],0);s.update(w['final'])
|
| 18 |
+
else:test.assertEqual([n(x) for x in s['velocity'][:2]],[0,0]);test.assertEqual(p['tail']['calls'],[])
|
| 19 |
+
test.assertEqual(p['final'],s)
|
| 20 |
+
else:
|
| 21 |
+
test.assertEqual(p['final'],route['final'])
|
| 22 |
+
if route['air']:check_air(test,route['air'],c)
|
| 23 |
+
if route['water']:
|
| 24 |
+
w=route['water'];check_swim(test,w,c)
|
| 25 |
+
if w['prefix']['fallback']:
|
| 26 |
+
mode=w['prefix']['fallback'];check_wrapper(test,mode['wrapper'],w['prefix']['normal']);s=copy.deepcopy(mode['wrapper']['final']);z=f(n(s['velocity'][2])-f(800*n(w['prefix']['dt'])));s['velocity'][2]=word(z)
|
| 27 |
+
if z<0:s['flags']&=~192;s['timer']=0
|
| 28 |
+
test.assertEqual(mode['mode_final'],s)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
class WalkingModeTests(unittest.TestCase):
|
| 32 |
+
@classmethod
|
| 33 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-walking-mode.json').read_text());cls.c={21160:100,21212:1,21220:5,21224:3000,**{int(a):n(v) for a,v in cls.r['constants'].items()}}
|
| 34 |
+
def test_all26_walking_or_delegated_states(self):
|
| 35 |
+
self.assertEqual(len(self.r['probes']),26)
|
| 36 |
+
for p in self.r['probes']:check(self,p,self.c)
|
| 37 |
+
def test_horizontal_zero_skips_wrapper_even_vertical_nonzero(self):
|
| 38 |
+
a,b=self.r['probes'][-2:]
|
| 39 |
+
for p in [a,b]:self.assertIsNone(p['wrapper']);self.assertFalse(p['final']['flags']&32)
|
| 40 |
+
self.assertEqual(n(a['final']['velocity'][2]),0);self.assertEqual(n(b['final']['velocity'][2]),1)
|
| 41 |
+
def test_main_actual_selected_walking_and_mode_handoff(self):
|
| 42 |
+
self.assertEqual(len(self.r['main_chains']),8);count=0
|
| 43 |
+
for m in self.r['main_chains']:
|
| 44 |
+
p=m['walking_mode'];self.assertEqual(p is not None,m['selected_mode']==43626);self.assertIsNotNone(m['posture']);self.assertEqual(len(m['environment']),4)
|
| 45 |
+
if p:
|
| 46 |
+
count+=1;check(self,p,self.c);self.assertEqual(p['route']['initial']['velocity'],m['at_mode']['velocity']);self.assertEqual(p['final']['velocity'],m['after_dispatch']['velocity']);self.assertEqual(p['final']['origin'],m['after_dispatch']['origin'])
|
| 47 |
+
else:self.assertEqual(m['selected_mode'],41768)
|
| 48 |
+
self.assertEqual(count,4)
|
| 49 |
+
def test_resource_and_entry_queue_survive_wrapper_and_main(self):
|
| 50 |
+
for m in self.r['main_chains']:
|
| 51 |
+
p=m['walking_mode']
|
| 52 |
+
if p:
|
| 53 |
+
self.assertEqual(m['walking_final']['184'],p['final']['meter']);self.assertEqual(m['walking_final']['108'],p['final']['queue']['sequence'])
|
| 54 |
+
if m['commands'][2]==10:self.assertEqual(p['final']['queue']['events'][0],99);self.assertIsNotNone(p['route']['air'])
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_wall_action.py
CHANGED
|
@@ -31,3 +31,6 @@ class WallActionTests(unittest.TestCase):
|
|
| 31 |
for p in self.r['probes']:
|
| 32 |
if p['air']:
|
| 33 |
check_air(self,p['air'],self.c);self.assertEqual(p['air']['initial']['velocity'],p['before_air']['velocity']);self.assertEqual(p['final']['velocity'],p['air']['final']['velocity']);self.assertEqual(p['final']['queue'],p['before_air']['queue'])
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
for p in self.r['probes']:
|
| 32 |
if p['air']:
|
| 33 |
check_air(self,p['air'],self.c);self.assertEqual(p['air']['initial']['velocity'],p['before_air']['velocity']);self.assertEqual(p['final']['velocity'],p['air']['final']['velocity']);self.assertEqual(p['final']['queue'],p['before_air']['queue'])
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_wall_probe.py
CHANGED
|
@@ -23,3 +23,6 @@ class WallProbeTests(unittest.TestCase):
|
|
| 23 |
for p in self.r['probes']:
|
| 24 |
self.assertEqual(len(p['calls']),int(p['request'] is not None))
|
| 25 |
if p['old_count']==5:self.assertIsNone(p['request'])
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
for p in self.r['probes']:
|
| 24 |
self.assertEqual(len(p['calls']),int(p['request'] is not None))
|
| 25 |
if p['old_count']==5:self.assertIsNone(p['request'])
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_water_entry.py
CHANGED
|
@@ -22,3 +22,6 @@ class WaterEntryTests(unittest.TestCase):
|
|
| 22 |
for j,q in enumerate(p['queries']):self.assertEqual(q['point'],base[:2]+[word(f(n(base[2])+4+16*j))]);self.assertEqual(q['entity'],7)
|
| 23 |
def test_no_event_or_inventory_cost_side_effect(self):
|
| 24 |
for p in self.r['probes']:self.assertEqual(p['final']['queue'],p['initial']['queue']);self.assertEqual(p['final']['meter'],p['initial']['meter']);self.assertEqual(p['final']['inventory'],p['initial']['inventory'])
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
for j,q in enumerate(p['queries']):self.assertEqual(q['point'],base[:2]+[word(f(n(base[2])+4+16*j))]);self.assertEqual(q['entity'],7)
|
| 23 |
def test_no_event_or_inventory_cost_side_effect(self):
|
| 24 |
for p in self.r['probes']:self.assertEqual(p['final']['queue'],p['initial']['queue']);self.assertEqual(p['final']['meter'],p['initial']['meter']);self.assertEqual(p['final']['inventory'],p['initial']['inventory'])
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
if __name__=='__main__':unittest.main()
|
scripts/test_qvm_water_route.py
CHANGED
|
@@ -36,3 +36,6 @@ class WaterRouteTests(unittest.TestCase):
|
|
| 36 |
for k,v in s.items():self.assertEqual(p['final'][k],v)
|
| 37 |
def test_call_order_no_prepared_fallback_on_failure(self):
|
| 38 |
for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[41486,41768] if p['fallback'] else [41486])
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
for k,v in s.items():self.assertEqual(p['final'][k],v)
|
| 37 |
def test_call_order_no_prepared_fallback_on_failure(self):
|
| 38 |
for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[41486,41768] if p['fallback'] else [41486])
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
if __name__=='__main__':unittest.main()
|