nmarshall commited on
Commit
cb6870c
·
1 Parent(s): ce0acfb

qvm: ordinary air movement

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -336,3 +336,6 @@ Research progress: [full40966 entry](research/QVM_JUMP_ENTRY.md) completes RE-54
336
 
337
 
338
  Research progress: [walking entry routing](research/QVM_WALK_ENTRY.md) completes RE-546 with24 prefix/4 main fixtures; full movement/native/platform work remains open.
 
 
 
 
336
 
337
 
338
  Research progress: [walking entry routing](research/QVM_WALK_ENTRY.md) completes RE-546 with24 prefix/4 main fixtures; full movement/native/platform work remains open.
339
+
340
+
341
+ Research progress: [ordinary air continuation](research/QVM_AIR_MODE.md) completes RE-547 with12 air/10 main fixtures. RE-548 retains wall/walking/other-mode/native/combined/full runtime and platform scope. No assets or Rust runtime change.
docs/FINDINGS.md CHANGED
@@ -694,3 +694,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
694
 
695
 
696
  **F-269 — Walking entry routing:**43626 deep level>2 plus positive forward/normal dot bypasses40966 for41848. Otherwise actual entry return1 selects41848 above level1 or42838, while return0 continues43683 with any updated up byte. Main timer/resource/event state is retained. [WALKENTRY-001](research/QVM_WALK_ENTRY.md).
 
 
 
 
694
 
695
 
696
  **F-269 — Walking entry routing:**43626 deep level>2 plus positive forward/normal dot bypasses40966 for41848. Otherwise actual entry return1 selects41848 above level1 or42838, while return0 continues43683 with any updated up byte. Main timer/resource/event state is retained. [WALKENTRY-001](research/QVM_WALK_ENTRY.md).
697
+
698
+
699
+ **F-270 — Ordinary air continuation:**42838 normalizes live planar basis, accelerates with file-backed coefficient1, optionally clips and calls gravity-on60091 without41768 tail. Four actual walking launches carry event99/animation/resource state into this movement;1499/1500 resource controls distinguish pre-cost launch202.5/270 from post-cost command scaling. Wall-specific and ordinary walking paths remain open. [AIRMODE-001](research/QVM_AIR_MODE.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -648,3 +648,6 @@ Research progress: [full40966 entry](research/QVM_JUMP_ENTRY.md) completes RE-54
648
 
649
 
650
  Research progress: [walking entry routing](research/QVM_WALK_ENTRY.md) completes RE-546 with24 prefix/4 main fixtures; full movement/native/platform work remains open.
 
 
 
 
648
 
649
 
650
  Research progress: [walking entry routing](research/QVM_WALK_ENTRY.md) completes RE-546 with24 prefix/4 main fixtures; full movement/native/platform work remains open.
651
+
652
+
653
+ Research progress: [ordinary air continuation](research/QVM_AIR_MODE.md) completes RE-547 with12 air/10 main fixtures. RE-548 retains wall/walking/other-mode/native/combined/full runtime and platform scope. No assets or Rust runtime change.
docs/RESEARCH_LEDGER.md CHANGED
@@ -437,3 +437,8 @@ Recovered the successful non-flags12 body with actual event99/queue and forced-a
437
  ## 2026-10-19 — RE-546 actual walking entry routing (separate task commit)
438
 
439
  Connected full40966 at actual43626 local108 boundary and main walking callback54433.24 standalone cases check initial deep-level/positive-dot bypass, reached entry/command byte mutation and level-dependent41848/42838 requests versus ordinary43683 continuation;4 main chains retain actual timer/action/query state and suppress walking effects under128 priority. Delegated movement and ordinary suffix effects remain explicitly omitted. Eight new independent tests pass; all711 tests pass. Prior main-contact/active-mode/flagged-mode reports and new walk-entry report regenerate byte-identically (new report263362 bytes). Storage/filter, links and whitespace pass. No assets/runtime/shared evaluator changed; native/reference/legal/full movement/platform work remains open.
 
 
 
 
 
 
437
  ## 2026-10-19 — RE-546 actual walking entry routing (separate task commit)
438
 
439
  Connected full40966 at actual43626 local108 boundary and main walking callback54433.24 standalone cases check initial deep-level/positive-dot bypass, reached entry/command byte mutation and level-dependent41848/42838 requests versus ordinary43683 continuation;4 main chains retain actual timer/action/query state and suppress walking effects under128 priority. Delegated movement and ordinary suffix effects remain explicitly omitted. Eight new independent tests pass; all711 tests pass. Prior main-contact/active-mode/flagged-mode reports and new walk-entry report regenerate byte-identically (new report263362 bytes). Storage/filter, links and whitespace pass. No assets/runtime/shared evaluator changed; native/reference/legal/full movement/platform work remains open.
440
+
441
+
442
+ ## 2026-10-19 — RE-547 ordinary42838 and walking-launch continuation (separate task commit)
443
+
444
+ Recovered ordinary air path after actual initial wall guard; unrecovered wall-specific body is explicitly rejected. Actual friction, copied-command scale, planar live-basis normalization, wish/acceleration coefficient1, optional inline overbounce clip and reusable60091 gravity-on first slide/conditional step/second slide/fallback share memory.12 standalone fixtures include6 reached step children.10 main chains attach4 reached walking-entry-to-air requests; resource1499/1500/4000 controls distinguish pre-cost launch202.5/270 from post-cost scaling at resource0/400, with numeric event99/animation/timer/resource persistence. Ordinary walking and higher-priority controls never receive delegated air effects. Eight independent tests verify helpers, exact arithmetic/basis/clip, both slides/step/wrapper, command-copy pointer and word configuration, source identity, guarded rejection and main handoffs. All719 tests pass. Prior contact-wrapper, main-contact, active-mode, flagged-mode and walk-entry reports regenerate byte-identically; new report reproduces twice byte-identically (725308 bytes). Storage/filter, links and whitespace pass. No assets/Rust runtime/shared evaluator changed. RE-548 retains wall-specific/ordinary walking/41848/combined producers/native/reference/main/scheduler/platform completion. This is task3 of the requested separately committed sequence.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -684,3 +684,7 @@ Purpose: turn the supplied installation into an evidence-backed specification of
684
 
685
 
686
  - [x] RE-546 Evaluate43626 deep-level bypass/full40966 return-dependent routing, command state and actual main54433 handoff ([WALKENTRY-001](research/QVM_WALK_ENTRY.md)).
 
 
 
 
 
684
 
685
 
686
  - [x] RE-546 Evaluate43626 deep-level bypass/full40966 return-dependent routing, command state and actual main54433 handoff ([WALKENTRY-001](research/QVM_WALK_ENTRY.md)).
687
+
688
+
689
+ - [x] RE-547 Evaluate ordinary42838 planar basis/wish/acceleration/clip and reusable60091/slide/step state, then attach reached walking-launch/main continuation with resource boundary controls ([AIRMODE-001](research/QVM_AIR_MODE.md)).
690
+ - [ ] RE-548 Recover wall-specific42838 and ordinary43626 suffix/41848, combined posture/ground/nested-action/query/movement and remaining main/scheduler/consumers, original reference execution/native collision ABI/legal domains and full macOS/Linux Rust/Bevy/Solari gameplay. Continue broad asset/rendering/protocol scope and platform prototype/first Rust slice.
docs/research/QVM_AIR_MODE.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Ordinary42838 air path and walking-launch continuation
2
+
3
+ RE-547 / F-270. Reproduce with `python3 scripts/analyze_qvm_air_mode.py`; check with `python3 scripts/test_qvm_air_mode.py`. The [machine report](qvm-air-mode.json) contains12 standalone ordinary-air fixtures and10 actual main chains. It connects [walking entry routing](QVM_WALK_ENTRY.md) to the reached42838 request. No original executable/full QVM/native collision/physics/rendering executes.
4
+
5
+ The actual42838 initial guard runs first. The wall-specific branch remains unrecovered and is explicitly rejected at42868 if that branch is reached. The ordinary path proceeds at43157. It evaluates current39988 friction, copies the24-byte command into a local frame and evaluates40397 at that actual copied-command pointer. Word-backed supplied command bytes and the child byte map agree; command scale reads the copied buttons and current post-entry resource.
6
+
7
+ The mode zeroes both forward/right basis Z components, normalizes the resulting planar vectors in live global memory, forms the horizontal wish from signed forward/right input, and normalizes that wish. Requested wish speed is its original length multiplied by command scale. Actual40275 uses initialized coefficient21192=1. Up input can affect scale but does not directly add wish Z here. Initial basis vectors are supplied finite inputs, not a claim that the original basis producer always returns those values.
8
+
9
+ A nonzero plane indicator applies the source overbounce clip to accelerated velocity using the current normal. Unlike55465's negative-dot-only, speed-restoring projection, this inline clip applies for either dot sign and does not normalize back to the previous magnitude. The mode clears flags32 and requests60091(1). Actual wrapper, first gravity-on57714, conditional59710 step/second slide, down/overlap traces and fallback stores share memory. Six standalone contact fixtures reach the step child. There is no extra41768 gravity tail after this wrapper; final42838 state is the wrapper's result.
10
+
11
+ The existing60091 implementation was factored into a reusable wrapper function while retaining the41768 composition's exact default output. The command-scale evaluator also accepts the actual copied-command pointer; its original callers keep their prior default pointer and reports.
12
+
13
+ Ten main chains include the prior up9/up10, flags32/160 and clear/contact controls plus resource1499/1500 boundary controls. Four actual walking launches request and evaluate this air path. Ordinary43683 continuation and higher-priority41768 controls never receive its effects. Source40966 event99, directional animation, ground clearing and resource deduction occur before air friction/scaling/slide. Resource4000 with inventory slot0=17 becomes400 and launches Z270;1500 becomes0 but still launches Z270 because launch choice precedes cost;1499 becomes0 and launches Z202.5. Air scaling consumes the resulting400/0 resource, preserving the distinction between launch choice and the following speed gate. Queue99, resource and leg-timer effects survive movement and the recorded main suffix under its stated omitted effects.
14
+
15
+ Eight independent tests predict friction, normalization and live basis stores, copied-command arguments, exact wish/acceleration and inline clip, both slide/step states and wrapper/fallback outputs, actual launch-to-air handoffs, resource/queue/timer ordering, wall-path rejection and file-backed configuration provenance. The suite now has719 passing tests. Prior wrapper/contact, main-contact, active-mode, flagged-mode and walk-entry reports regenerate byte-identically. Storage/filter, links, whitespace and deterministic new-report size are recorded in the ledger.
16
+
17
+ Native roots and ordered slide/down/overlap records/endpoints remain supplied, not collision-derived. Complete wall-specific42838, ordinary43626 suffix,41848, combined posture/ground/nested-action ordering, remaining main prefix/suffix/consumers, original reference traces/native ABI/legal domains, full scheduler and macOS/Linux Rust/Bevy/Solari gameplay remain open under RE-548. This task adds no Rust runtime or platform proof.
docs/research/QVM_WALK_ENTRY.md CHANGED
@@ -11,3 +11,6 @@ The standalone grid varies level0/2/3, supplied forward Z−3/0, up9/10 and flag
11
  This report stops at normal continuation43683 or delegated jump45199. Ordinary walking suffix and requested41848/42838 effects remain omitted here. Source main callback applies at54433 after43626's actual CALL/POP. Native roots, level/basis/normal/ground/input state remain supplied; no original executable/full QVM/native collision/physics/rendering executes. A later task can attach recovered42838 effects to this explicit request boundary.
12
 
13
  Eight independent tests check prefix/deep-level priority, full helper state/child formulas, delegated target and stop, held-up byte propagation, actual main gating, timer/resource/event order and source/scope. Full-suite/regeneration/storage/link/whitespace results are recorded in the ledger. Complete walking and other modes, native/reference/legal domains, full main/scheduler and Rust/Bevy/Solari platform gameplay remain open.
 
 
 
 
11
  This report stops at normal continuation43683 or delegated jump45199. Ordinary walking suffix and requested41848/42838 effects remain omitted here. Source main callback applies at54433 after43626's actual CALL/POP. Native roots, level/basis/normal/ground/input state remain supplied; no original executable/full QVM/native collision/physics/rendering executes. A later task can attach recovered42838 effects to this explicit request boundary.
12
 
13
  Eight independent tests check prefix/deep-level priority, full helper state/child formulas, delegated target and stop, held-up byte propagation, actual main gating, timer/resource/event order and source/scope. Full-suite/regeneration/storage/link/whitespace results are recorded in the ledger. Complete walking and other modes, native/reference/legal domains, full main/scheduler and Rust/Bevy/Solari platform gameplay remain open.
14
+
15
+
16
+ Follow-up: [ordinary42838 continuation](QVM_AIR_MODE.md) attaches reached air movement to successful launch, retaining ordinary walking/deep-water gaps. The earlier prefix-only report remains byte-identical.
docs/research/README.md CHANGED
@@ -249,3 +249,6 @@ The extension collector adds five focused tests for native tail calls, command-r
249
 
250
 
251
  [Walking43626 entry routing](QVM_WALK_ENTRY.md) adds RE-546. Reproduce with `python3 scripts/analyze_qvm_walk_entry.py`; check with `python3 scripts/test_qvm_walk_entry.py`. Ordinary/delegated movement suffixes remain omitted in these prefix fixtures.
 
 
 
 
249
 
250
 
251
  [Walking43626 entry routing](QVM_WALK_ENTRY.md) adds RE-546. Reproduce with `python3 scripts/analyze_qvm_walk_entry.py`; check with `python3 scripts/test_qvm_walk_entry.py`. Ordinary/delegated movement suffixes remain omitted in these prefix fixtures.
252
+
253
+
254
+ [Ordinary42838 air path](QVM_AIR_MODE.md) adds RE-547. Reproduce with `python3 scripts/analyze_qvm_air_mode.py`; check with `python3 scripts/test_qvm_air_mode.py`. Actual walking launch can continue through recovered air/wrapper/step/slides; wall-specific/ordinary walking/native/runtime remain open.
docs/research/qvm-air-mode.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_active_mode.py CHANGED
@@ -24,9 +24,9 @@ CONSTANTS=[21160,21200,21208,21212,21220,21224,21228]
24
  def initialized(raw,h):return {a:int.from_bytes(raw[h['data_offset']+a:h['data_offset']+a+4],'little') for a in CONSTANTS}
25
 
26
 
27
- def command_scale(ins,m,cmd):
28
- movement=[v&255 for v in cmd];root=word(math.sqrt(sum(s8(v)**2 for v in movement)));t=trace_slice(ins,40398,40677,m,{60:FRAME+4},byte_memory={FRAME+25+i:v for i,v in enumerate(movement)},call_results={40655:root},halt_on_leave=True,capture_stack=True,local_base=SCALE_FRAME,limit=512)
29
- return t['memory'],{'movement_bytes':movement,'buttons_word':m[FRAME+20],'meter_word':m[PS+184],'supplied_sqrt_word':root,'result_scale_float_word':t['stack'][-1]&0xffffffff,'calls':t['calls'],**trace_fields(t,False)}
30
 
31
 
32
  def accelerate(ins,m,args):
 
24
  def initialized(raw,h):return {a:int.from_bytes(raw[h['data_offset']+a:h['data_offset']+a+4],'little') for a in CONSTANTS}
25
 
26
 
27
+ def command_scale(ins,m,cmd,cmd_pointer=FRAME+4):
28
+ movement=[v&255 for v in cmd];root=word(math.sqrt(sum(s8(v)**2 for v in movement)));t=trace_slice(ins,40398,40677,m,{60:cmd_pointer},byte_memory={cmd_pointer+21+i:v for i,v in enumerate(movement)},call_results={40655:root},halt_on_leave=True,capture_stack=True,local_base=SCALE_FRAME,limit=512)
29
+ return t['memory'],{'movement_bytes':movement,'buttons_word':m[cmd_pointer+16],'meter_word':m[PS+184],'supplied_sqrt_word':root,'result_scale_float_word':t['stack'][-1]&0xffffffff,'calls':t['calls'],**trace_fields(t,False)}
30
 
31
 
32
  def accelerate(ins,m,args):
scripts/analyze_qvm_air_mode.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Ordinary42838 path and actual walking-launch/main composition."""
3
+ import itertools,json
4
+ from pathlib import Path
5
+ from analyze_qvm import decode,write_json
6
+ from analyze_deferred_auth import trace_slice
7
+ from analyze_bsp_references import trace_fields
8
+ from analyze_qvm_acceleration import PS,FRAME,word,number
9
+ from analyze_qvm_traversal_query import root_word
10
+ from analyze_qvm_friction import friction_probe
11
+ from analyze_qvm_active_mode import initialized,command_scale,accelerate
12
+ from analyze_qvm_contact_callers import wrapper,snapshot
13
+ from analyze_qvm_flagged_mode import seed
14
+ from analyze_qvm_walk_entry import main_case
15
+ from analyze_vm_extensions import verified
16
+
17
+ LOCAL=0x63000000
18
+
19
+
20
+ def air(ins,m,cmd,pattern='clear'):
21
+ m=dict(m);initial=snapshot(m);initial_basis=[vec(m,a) for a in [35023892,35023904]]
22
+ # Preserve actual wall-path guard instructions, reject the unrecovered body.
23
+ guard=trace_slice(ins,42839,43157,m,{},stop_targets=[42868],local_base=LOCAL,limit=256)
24
+ if guard['stop']==42868:raise ValueError('42838 wall-specific path outside ordinary-path model')
25
+ m=guard['memory'];pc=43157;trace=guard['trace'][:];calls=guard['calls'][:];friction=None;scale=None;roots={43224:0,43296:0,43419:0};wish=None;ap=None;at_clip=None;after_clip=None;w=None
26
+ for i in [4,8,12,16]:m.setdefault(FRAME+i,0)
27
+ m[FRAME+24]=sum((v&255)<<(8*(i+1)) for i,v in enumerate(cmd))
28
+ while True:
29
+ t=trace_slice(ins,43157,43624,m,{},resume_at=pc,stop_targets=[s for s in [43160,43190,43200,43276,43395,43474,43604] if s!=pc],byte_memory={FRAME+25+i:v&255 for i,v in enumerate(cmd)},local_base=LOCAL,call_results=roots,limit=2048);m=t['memory'];trace+=t['trace'];calls+=t['calls'];pc=t['stop']
30
+ if pc==43160:m,friction=friction_probe(ins,{},(0,0,0),initial_memory=m,return_memory=True)
31
+ elif pc==43190:m,scale=command_scale(ins,m,cmd,LOCAL+80);m[LOCAL+196]=scale['result_scale_float_word']
32
+ elif pc==43200:roots[43224]=root_word([number(v) for v in vec(m,35023892)])
33
+ elif pc==43276:roots[43296]=root_word([number(v) for v in vec(m,35023904)])
34
+ elif pc==43395:wish=vec(m,LOCAL+36);roots[43419]=root_word([number(v) for v in wish])
35
+ elif pc==43474:m,ap=accelerate(ins,m,t['calls'][-1]['args']);at_clip=vec(m,PS+32)
36
+ elif pc==43604:after_clip=vec(m,PS+32)
37
+ elif pc==43624:m,w=wrapper(ins,m,pattern,'clear','clear',1);break
38
+ else:raise AssertionError('Unexpected42838 ordinary boundary')
39
+ return m,{'initial':initial,'commands':list(cmd),'initial_basis':initial_basis,'basis_after':[vec(m,a) for a in [35023892,35023904]],'normal':vec(m,35023968),'plane':m[35023940],'friction':friction,'scale':scale,'roots':{str(a):v for a,v in roots.items()},'wish':wish,'acceleration':ap,'before_clip':at_clip,'after_clip':after_clip,'wrapper':w,'final':snapshot(m),'calls':calls,**trace_fields({'trace':trace},False)}
40
+
41
+
42
+ def vec(m,a):return [m[a+4*i]&0xffffffff for i in range(3)]
43
+
44
+
45
+ def main():
46
+ q=json.loads(Path('docs/research/qvm/qagame.json').read_text());raw=verified(Path(q['source']['member']['output']).read_bytes(),q['sha256']);h,ins=decode(raw);constants=initialized(raw,h);a=21192;constants[a]=int.from_bytes(raw[h['data_offset']+a:h['data_offset']+a+4],'little')
47
+ probes=[]
48
+ for cmd,plane,pattern in itertools.product([(0,0,0),(100,0,0),(-128,127,0)],[0,1],['clear','contacts']):
49
+ m=seed(constants,cmd,plane,32);m[PS+220]=0;probes.append(air(ins,m,cmd,pattern)[1])
50
+ chains=[]
51
+ for up,flags,pattern in itertools.product([9,10],[32,160],['clear','contacts']):
52
+ def effect(ins,m,cmd):return air(ins,m,cmd,pattern)
53
+ p=main_case(ins,constants,up,flags,effect);p['air_pattern']=pattern;p['input_meter']=4000;chains.append(p)
54
+ for meter in [1499,1500]:
55
+ def effect(ins,m,cmd):return air(ins,m,cmd,'clear')
56
+ p=main_case(ins,constants,10,32,effect,meter=meter);p.update({'air_pattern':'clear','input_meter':meter});chains.append(p)
57
+ write_json(Path('docs/research/qvm-air-mode.json'),{'source':q['source'],'sha256':q['sha256'],'initialized_words':{str(a):v for a,v in constants.items()},'ordinary_instructions':ins[43157:43626],'probes':probes,'main_chains':chains,'limitations':'Bounded finite synthetic ordinary42838 composition; no original executable/full QVM/native collision/physics/rendering executes. Actual entry guard rejects unrecovered wall-specific body, then friction/copied-command scale/planar basis normalization/acceleration/optional plane clip/60091 gravity-on wrapper and reached slides/step share memory. Native roots and ordered trace records/interpolated endpoints remain supplied, not collision-derived. Actual43626 successful entry can delegate to this path inside main; ordinary walking43683 and41848 effects remain omitted. Other environment/modes/main prefix-suffix/native consumers/legal collision domains/full scheduler/macOS/Linux/Rust/Bevy/Solari gameplay remain open.'});print('Recovered ordinary42838 and actual walking-launch continuation')
58
+
59
+
60
+ if __name__=='__main__':main()
scripts/analyze_qvm_contact_callers.py CHANGED
@@ -32,18 +32,22 @@ def step(ins,m,args,records,policy):
32
  elif t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':return m,{'initial':initial,'at_slide':at_slide,'slide':slide,'requests':requests,'return_word':t['stack'][-1],'final':snapshot(m),'calls':calls,**trace_fields({'trace':trace},False)}
33
 
34
 
35
- def composition(ins,first_name,timer,policy,second_name,initial_memory=None,return_memory=False):
36
- ground=int(first_name=='early');m=seed(flags=2208,timer=timer,plane=ground) if initial_memory is None else dict(initial_memory)
37
- if initial_memory is None:m[35024000]=word(0)
38
- initial=snapshot(m);pre=trace_slice(ins,41769,41846,m,{},stop_targets=[41789],local_base=MODE);m=pre['memory'];before_wrapper=snapshot(m);pc=60092;calls=[];trace=[];first=None;stepped=None
39
  patterns={'clear':[{'fraction':1,'normal':[0,0,1],'entity':8}],'contacts':specs([(1,0,0)]*4),'early':specs([(0,0,-1)]*4)}
40
  while True:
41
- t=trace_slice(ins,60092,60213,m,{92:1} if pc==60092 else {},resume_at=pc,stop_targets=[s for s in [60113,60148] if s!=pc],local_base=WRAP,halt_on_leave=True,capture_stack=True,limit=512);m=t['memory'];calls+=t['calls'];trace+=t['trace'];pc=t['stop']
42
- if pc==60113:m,first=child(ins,m,patterns[first_name],1,'first_slide');m[WRAP+48]=first['return_word']
43
  elif pc==60148:m,stepped=step(ins,m,t['calls'][-1]['args'],patterns[second_name],policy);m[WRAP+76]=stepped['return_word']
44
- elif t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':wrapper={'before':before_wrapper,'first_slide':first,'step':stepped,'return_word':t['stack'][-1],'final':snapshot(m),'calls':calls,**trace_fields({'trace':trace},False)};break
 
 
 
 
 
 
45
  post=trace_slice(ins,41769,41846,m,{},resume_at=41789,local_base=MODE)
46
- report={'first_pattern':first_name,'step_pattern':second_name,'policy':policy,'initial':initial,'wrapper':wrapper,'mode_final':snapshot(post['memory']),'mode_calls':pre['calls']+post['calls']}
47
  return (post['memory'],report) if return_memory else report
48
 
49
 
 
32
  elif t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':return m,{'initial':initial,'at_slide':at_slide,'slide':slide,'requests':requests,'return_word':t['stack'][-1],'final':snapshot(m),'calls':calls,**trace_fields({'trace':trace},False)}
33
 
34
 
35
+ def wrapper(ins,m,first_name,policy,second_name,gravity=1):
36
+ before_wrapper=snapshot(m);pc=60092;calls=[];trace=[];first=None;stepped=None
 
 
37
  patterns={'clear':[{'fraction':1,'normal':[0,0,1],'entity':8}],'contacts':specs([(1,0,0)]*4),'early':specs([(0,0,-1)]*4)}
38
  while True:
39
+ t=trace_slice(ins,60092,60213,m,{92:gravity} if pc==60092 else {},resume_at=pc,stop_targets=[s for s in [60113,60148] if s!=pc],local_base=WRAP,halt_on_leave=True,capture_stack=True,limit=512);m=t['memory'];calls+=t['calls'];trace+=t['trace'];pc=t['stop']
40
+ if pc==60113:m,first=child(ins,m,patterns[first_name],gravity,'first_slide');m[WRAP+48]=first['return_word']
41
  elif pc==60148:m,stepped=step(ins,m,t['calls'][-1]['args'],patterns[second_name],policy);m[WRAP+76]=stepped['return_word']
42
+ elif t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':return m,{'before':before_wrapper,'first_slide':first,'step':stepped,'return_word':t['stack'][-1],'final':snapshot(m),'calls':calls,**trace_fields({'trace':trace},False)}
43
+
44
+
45
+ def composition(ins,first_name,timer,policy,second_name,initial_memory=None,return_memory=False):
46
+ ground=int(first_name=='early');m=seed(flags=2208,timer=timer,plane=ground) if initial_memory is None else dict(initial_memory)
47
+ if initial_memory is None:m[35024000]=word(0)
48
+ initial=snapshot(m);pre=trace_slice(ins,41769,41846,m,{},stop_targets=[41789],local_base=MODE);m=pre['memory'];m,w=wrapper(ins,m,first_name,policy,second_name)
49
  post=trace_slice(ins,41769,41846,m,{},resume_at=41789,local_base=MODE)
50
+ report={'first_pattern':first_name,'step_pattern':second_name,'policy':policy,'initial':initial,'wrapper':w,'mode_final':snapshot(post['memory']),'mode_calls':pre['calls']+post['calls']}
51
  return (post['memory'],report) if return_memory else report
52
 
53
 
scripts/analyze_qvm_walk_entry.py CHANGED
@@ -29,8 +29,8 @@ def route(ins,m,cmd,air_effect=None):
29
  return m,{'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)}
30
 
31
 
32
- def main_case(ins,constants,up,flags,air_effect=None):
33
- cmd=(100,0,up);m=seed(constants,cmd,1,flags);m.update({PS+72:77,PS+220:0,PS+184:4000,PS+376:17})
34
  def act(ins,m):return action(ins,m,0,PATTERNS['none'])
35
  def query(ins,m):return coupled(ins,m,{'forward':100,'fractions':(1,1)})
36
  def walk(ins,m):return route(ins,m,cmd,air_effect)
 
29
  return m,{'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)}
30
 
31
 
32
+ def main_case(ins,constants,up,flags,air_effect=None,meter=4000):
33
+ cmd=(100,0,up);m=seed(constants,cmd,1,flags);m.update({PS+72:77,PS+220:0,PS+184:meter,PS+376:17})
34
  def act(ins,m):return action(ins,m,0,PATTERNS['none'])
35
  def query(ins,m):return coupled(ins,m,{'forward':100,'fractions':(1,1)})
36
  def walk(ins,m):return route(ins,m,cmd,air_effect)
scripts/test_qvm_air_mode.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Independent ordinary-air basis/wish/clip/wrapper and launch-chain oracles."""
3
+ import hashlib,json,math
4
+ from pathlib import Path
5
+ import unittest
6
+ from test_qvm_ground import word,n,f
7
+ from test_qvm_traversal_query import direction_oracle
8
+ from test_qvm_acceleration import scale_oracle,accel_oracle,s8
9
+ from test_qvm_friction import friction_oracle
10
+ from test_qvm_slide_planes import clip
11
+ from test_qvm_slide_repeated import oracle as slide_oracle
12
+ from test_qvm_contact_callers import expected_step
13
+ from test_qvm_jump_entry import check as check_entry
14
+
15
+
16
+ def norm(words):
17
+ v=list(map(n,words));return word(math.sqrt(f(f(f(v[0]*v[0])+f(v[1]*v[1]))+f(v[2]*v[2]))))
18
+
19
+
20
+ def check(test,p,c):
21
+ fr=p['friction'];root,drop,ratio,velocity=friction_oracle(fr,c);test.assertEqual([fr['supplied_sqrt_word'],fr['drop_float_word'],fr['ratio_float_word'],fr['result_velocity_float_words']],[root,drop,ratio,velocity]);test.assertEqual(fr['initial_velocity_float_words'],p['initial']['velocity'])
22
+ forward,rf,_=direction_oracle(p['initial_basis'][0][:2]);right,rr,_=direction_oracle(p['initial_basis'][1][:2]);test.assertEqual(p['basis_after'],[list(map(word,forward)),list(map(word,right))]);test.assertEqual([p['roots']['43224'],p['roots']['43296']],[rf,rr]);test.assertEqual(p['scale']['result_scale_float_word'],scale_oracle(p['scale']))
23
+ fw,rt,_=map(s8,p['scale']['movement_bytes']);wish=[word(f(f(forward[i]*fw)+f(right[i]*rt))) for i in range(2)]+[0];test.assertEqual(p['wish'],wish);root=norm(wish);test.assertEqual(p['roots']['43419'],root);length=n(root);direction=[word(f(n(v)*f(1/length))) for v in wish] if length else wish
24
+ ap=p['acceleration'];test.assertEqual(ap['initial_velocity_float_words'],velocity);test.assertEqual([ap['direction_float_words'],ap['wish_speed_float_word'],ap['acceleration_float_word']],[direction,word(f(length*n(p['scale']['result_scale_float_word']))),word(c[21192])]);test.assertEqual([ap['projection_float_word'],ap['gap_float_word'],ap['amount_float_word'],ap['result_velocity_float_words']],list(accel_oracle(ap,velocity)));test.assertEqual(p['before_clip'],ap['result_velocity_float_words']);expected_clip=clip(list(map(n,p['before_clip'])),list(map(n,p['normal']))) if p['plane'] else p['before_clip'];test.assertEqual(p['after_clip'],expected_clip)
25
+ w=p['wrapper'];test.assertEqual(w['before']['velocity'],expected_clip);test.assertEqual(w['before']['flags'],fr['ps_flags_word']&~32);first=w['first_slide'];slide_oracle(test,first,{**w['before'],'ground_normal':p['normal']});test.assertEqual(first['gravity'],1);s=w['step']
26
+ if s:
27
+ slide_oracle(test,s['slide'],{**s['at_slide'],'ground_normal':p['normal']});ret,origin,v,flags=expected_step(s);test.assertEqual([s['return_word'],s['final']['origin'],s['final']['velocity'],s['final']['flags']],[ret,origin,v,flags])
28
+ if not ret:origin=first['final']['origin'];v=first['final']['velocity'];flags|=32
29
+ delta=f(n(origin[2])-n(w['before']['origin'][2]));height=int(delta) if delta>2 else p['initial']['height']
30
+ else:origin,v,flags,height=first['final']['origin'],first['final']['velocity'],first['final']['flags'],p['initial']['height']
31
+ test.assertEqual([w['final']['origin'],w['final']['velocity'],w['final']['flags'],w['final']['height']],[origin,v,flags,height]);test.assertEqual(p['final'],w['final'])
32
+
33
+
34
+ class QvmAirModeTests(unittest.TestCase):
35
+ @classmethod
36
+ def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-air-mode.json').read_text());cls.c={int(a):n(v) for a,v in cls.r['initialized_words'].items()}
37
+ def test_all_ordinary_air_children_and_wrapper_state(self):
38
+ self.assertEqual(len(self.r['probes']),12)
39
+ for p in self.r['probes']:check(self,p,self.c)
40
+ def test_planar_normalization_mutates_live_basis_before_wish(self):
41
+ for p in self.r['probes']:self.assertEqual(p['initial_basis'],list(map(lambda v:list(map(word,v)),[(3,4,0),(-4,3,0)])));self.assertEqual(p['basis_after'],list(map(lambda v:list(map(word,v)),[(n(word(.6)),n(word(.8)),0),(n(word(-.8)),n(word(.6)),0)])))
42
+ def test_copied_command_pointer_and_scale_inputs(self):
43
+ for p in self.r['probes']:
44
+ c=next(c for c in p['calls'] if c['target']==40397);self.assertEqual(c['args'],{'8':0x63000050});self.assertEqual(p['scale']['movement_bytes'],[v&255 for v in p['commands']]);self.assertEqual(p['scale']['buttons_word'],256)
45
+ def test_plane_clip_and_no_extra_mode_gravity_tail(self):
46
+ self.assertTrue(any(p['before_clip']!=p['after_clip'] for p in self.r['probes'] if p['plane']))
47
+ for p in self.r['probes']:self.assertEqual(p['final']['velocity'],p['wrapper']['final']['velocity']);self.assertEqual([c['target'] for c in p['calls']],[39988,40397,-107,-107,-107,40275,60091])
48
+ def test_successful_main_walk_entry_delegates_only_reached_air(self):
49
+ self.assertEqual(len(self.r['main_chains']),10);count=0
50
+ for p in self.r['main_chains']:
51
+ w=p['walking_mode']
52
+ if w:
53
+ check_entry(self,w['entry']);expected=p['up']==10;self.assertEqual(w['air'] is not None,expected)
54
+ if expected:
55
+ count+=1;a=w['air'];check(self,a,self.c);self.assertEqual(a['initial']['velocity'],w['entry']['final']['velocity']);self.assertEqual(a['initial']['flags'],w['entry']['final']['flags']);self.assertEqual(w['final']['velocity'],a['final']['velocity']);self.assertEqual(p['final']['velocity'],a['final']['velocity']);self.assertEqual(p['final']['origin'],a['final']['origin'])
56
+ else:self.assertEqual(p['selected_mode'],41768)
57
+ self.assertEqual(count,4)
58
+ def test_launch_queue_resource_and_timer_survive_actual_movement(self):
59
+ seen=set()
60
+ for p in self.r['main_chains']:
61
+ w=p['walking_mode']
62
+ if w and w['air']:
63
+ seen.add((p['input_meter'],w['air']['scale']['meter_word'],n(w['air']['initial']['velocity'][2])))
64
+ self.assertEqual(p['walking_final']['108'],1);self.assertEqual(p['walking_final']['112'],99);self.assertEqual(p['walking_final']['184'],w['entry']['final']['meter']);self.assertEqual(w['air']['scale']['meter_word'],w['entry']['final']['meter']);self.assertEqual(p['walking_final']['72'],0);self.assertEqual(w['air']['plane'],0);self.assertGreater(n(w['air']['initial']['velocity'][2]),0)
65
+ self.assertEqual(seen,{(4000,400,270),(1500,0,270),(1499,0,202.5)})
66
+ def test_unrecovered_wall_specific_path_rejected(self):
67
+ from analyze_qvm import decode
68
+ from analyze_qvm_flagged_mode import seed
69
+ from analyze_qvm_air_mode import air
70
+ q=json.loads(Path('docs/research/qvm/qagame.json').read_text());_,ins=decode(Path(q['source']['member']['output']).read_bytes());m=seed({int(a):v for a,v in self.r['initialized_words'].items()},(0,0,0),0,2048)
71
+ with self.assertRaisesRegex(ValueError,'wall-specific path'):air(ins,m,(0,0,0))
72
+ def test_source_configuration_and_explicit_scope(self):
73
+ 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['ordinary_instructions'][0]['index'],43157);self.assertEqual(self.r['ordinary_instructions'][-1]['index'],43625);self.assertEqual(self.c[21192],1)
74
+ from analyze_qvm import decode
75
+ raw=Path(q['source']['member']['output']).read_bytes();header,_=decode(raw)
76
+ for a,v in self.r['initialized_words'].items():self.assertEqual(int.from_bytes(raw[header['data_offset']+int(a):header['data_offset']+int(a)+4],'little'),v)
77
+ for phrase in ['no original executable/full QVM/native collision/physics/rendering executes','wall-specific body','not collision-derived','ordinary walking43683 and41848 effects remain omitted']:self.assertIn(phrase,self.r['limitations'])
78
+
79
+
80
+ if __name__=='__main__':unittest.main()