nmarshall commited on
Commit
4485bf8
·
1 Parent(s): 284b287

qvm: wall action continuation

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -349,3 +349,6 @@ Research progress: RE-550 [report](research/QVM_DIRECTION_CODEC.md); remaining n
349
 
350
 
351
  Research progress: RE-551 [report](research/QVM_WALL_PROBE.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
349
 
350
 
351
  Research progress: RE-551 [report](research/QVM_WALL_PROBE.md); remaining native/content/runtime/platform scope stays open.
352
+
353
+
354
+ Research progress: RE-552 [report](research/QVM_WALL_ACTION.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -707,3 +707,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
707
 
708
 
709
  **RE-551 — Recover42838 wall guard and trace hull restoration:** Wall probe requires2048, a strict negative-Z interval and count below configuration. It shifts the endpoint five units opposite stored XY normal, temporarily sets hull min-Z10, restores min-Z, and sets count10 on fraction>=1. PS440 aliases inventory slot16 in the captured17-slot view. [Evidence](research/QVM_WALL_PROBE.md).
 
 
 
 
707
 
708
 
709
  **RE-551 — Recover42838 wall guard and trace hull restoration:** Wall probe requires2048, a strict negative-Z interval and count below configuration. It shifts the endpoint five units opposite stored XY normal, temporarily sets hull min-Z10, restores min-Z, and sets count10 on fraction>=1. PS440 aliases inventory slot16 in the captured17-slot view. [Evidence](research/QVM_WALL_PROBE.md).
710
+
711
+
712
+ **RE-552 — Compose wall success entry events and air continuation:** Successful40966 is followed by counter increment, a second resource check after entry cost, a100/200 horizontal wall impulse, event86 with actual direction-codec parameter and forced animation26 before ordinary air movement. [Evidence](research/QVM_WALL_ACTION.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -661,3 +661,6 @@ Research progress: RE-550 [report](research/QVM_DIRECTION_CODEC.md); remaining n
661
 
662
 
663
  Research progress: RE-551 [report](research/QVM_WALL_PROBE.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
661
 
662
 
663
  Research progress: RE-551 [report](research/QVM_WALL_PROBE.md); remaining native/content/runtime/platform scope stays open.
664
+
665
+
666
+ Research progress: RE-552 [report](research/QVM_WALL_ACTION.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -457,3 +457,8 @@ Encoder uses strict-greater positive dot search initialized to score0/index0, so
457
  ## 2026-10-19 — RE-551 Recover42838 wall guard and trace hull restoration (separate task commit)
458
 
459
  Wall probe requires2048, a strict negative-Z interval and count below configuration. It shifts the endpoint five units opposite stored XY normal, temporarily sets hull min-Z10, restores min-Z, and sets count10 on fraction>=1. PS440 aliases inventory slot16 in the captured17-slot view. 32 guard/fraction controls and four independent tests cover gate order, endpoint/pointers/mask, temporary hull restoration and pending-success versus failure state. Full suite: 731 tests pass. Report regenerates byte-identically (91980 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
457
  ## 2026-10-19 — RE-551 Recover42838 wall guard and trace hull restoration (separate task commit)
458
 
459
  Wall probe requires2048, a strict negative-Z interval and count below configuration. It shifts the endpoint five units opposite stored XY normal, temporarily sets hull min-Z10, restores min-Z, and sets count10 on fraction>=1. PS440 aliases inventory slot16 in the captured17-slot view. 32 guard/fraction controls and four independent tests cover gate order, endpoint/pointers/mask, temporary hull restoration and pending-success versus failure state. Full suite: 731 tests pass. Report regenerates byte-identically (91980 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
460
+
461
+
462
+ ## 2026-10-19 — RE-552 Compose wall success entry events and air continuation (separate task commit)
463
+
464
+ Successful40966 is followed by counter increment, a second resource check after entry cost, a100/200 horizontal wall impulse, event86 with actual direction-codec parameter and forced animation26 before ordinary air movement. 24 entry/configuration/resource/continuation fixtures and four independent tests predict both event slots, post-cost velocity, alias counter, real codec and full air/wrapper outputs. Full suite: 735 tests pass. Report regenerates byte-identically (522953 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
@@ -698,3 +698,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
698
 
699
 
700
  - [x] RE-551 Recover42838 wall guard and trace hull restoration ([report](research/QVM_WALL_PROBE.md)).
 
 
 
 
698
 
699
 
700
  - [x] RE-551 Recover42838 wall guard and trace hull restoration ([report](research/QVM_WALL_PROBE.md)).
701
+
702
+
703
+ - [x] RE-552 Compose wall success entry events and air continuation ([report](research/QVM_WALL_ACTION.md)).
docs/research/QVM_WALL_ACTION.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Compose wall success entry events and air continuation
2
+
3
+ RE-552. Reproduce with `python3 scripts/analyze_qvm_wall_action.py`; check with `python3 scripts/test_qvm_wall_action.py`. The [machine report](qvm-wall-action.json) retains source identity and bounded fixtures.
4
+
5
+ Task551's hit boundary now evaluates actual40966. Return0 skips the boost/event suffix. Return1 increments PS440, checks current resource and state128, subtracts100 from current Z in the reduced case and adds stored XY normal times100 or200. This resource test occurs after40966's cost, so an initially full launch may receive the reduced wall boost. Actual60317 encodes the stored planar normal for29913 event86; that follows entry event99 in the two-slot queue. Actual39525(26) follows, then the recovered ordinary43157 path can continue without re-running the wall guard. Existing ordinary-air and codec default reports remain compatible. Native fractions/roots/slide records remain supplied; initial geometry/configuration and full main/environment/platform legality 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
@@ -262,3 +262,6 @@ The extension collector adds five focused tests for native tail calls, command-r
262
 
263
 
264
  [RE-551: Recover42838 wall guard and trace hull restoration](QVM_WALL_PROBE.md). Reproduce with `python3 scripts/analyze_qvm_wall_probe.py`; check with `python3 scripts/test_qvm_wall_probe.py`.
 
 
 
 
262
 
263
 
264
  [RE-551: Recover42838 wall guard and trace hull restoration](QVM_WALL_PROBE.md). Reproduce with `python3 scripts/analyze_qvm_wall_probe.py`; check with `python3 scripts/test_qvm_wall_probe.py`.
265
+
266
+
267
+ [RE-552: Compose wall success entry events and air continuation](QVM_WALL_ACTION.md). Reproduce with `python3 scripts/analyze_qvm_wall_action.py`; check with `python3 scripts/test_qvm_wall_action.py`.
docs/research/qvm-wall-action.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_air_mode.py CHANGED
@@ -17,10 +17,10 @@ from analyze_vm_extensions import verified
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)
 
17
  LOCAL=0x63000000
18
 
19
 
20
+ def air(ins,m,cmd,pattern='clear',resume_ordinary=False):
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={'memory':m,'trace':[],'calls':[],'stop':43157} if resume_ordinary else 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)
scripts/analyze_qvm_direction_codec.py CHANGED
@@ -14,11 +14,11 @@ VEC=0x51000
14
  def table(raw,h):return constants(raw,h,list(range(21732,21732+162*12,4))+[21348,21352,21356])
15
 
16
 
17
- def encode(ins,m,vector):
18
  m=dict(m)
19
  if vector is not None:
20
- for i,v in enumerate(vector):m[VEC+4*i]=v
21
- t=trace_slice(ins,60318,60406,m,{40:0 if vector is None else VEC},local_base=BASE,halt_on_leave=True,capture_stack=True,limit=20000);return t['memory'],{'vector':vector,'result':t['stack'][-1],'calls':t['calls'],**trace_fields(t,False)}
22
 
23
 
24
  def decode_vector(ins,m,index):
 
14
  def table(raw,h):return constants(raw,h,list(range(21732,21732+162*12,4))+[21348,21352,21356])
15
 
16
 
17
+ def encode(ins,m,vector,pointer=VEC):
18
  m=dict(m)
19
  if vector is not None:
20
+ for i,v in enumerate(vector):m[pointer+4*i]=v
21
+ t=trace_slice(ins,60318,60406,m,{40:0 if vector is None else pointer},local_base=BASE,halt_on_leave=True,capture_stack=True,limit=20000);return t['memory'],{'vector':vector,'result':t['stack'][-1],'calls':t['calls'],**trace_fields(t,False)}
22
 
23
 
24
  def decode_vector(ins,m,index):
scripts/analyze_qvm_wall_action.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Wall success with real entry, direction codec, numeric events and air continuation."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source,memory,execute
6
+ from analyze_qvm import write_json
7
+ from analyze_qvm_acceleration import PS,word
8
+ from analyze_qvm_wall_probe import wall_probe,LOCAL
9
+ from analyze_qvm_jump_entry import entry,snapshot
10
+ from analyze_qvm_direction_codec import table,encode
11
+ from analyze_qvm_landing import event
12
+ from analyze_qvm_animation_contacts import evaluate
13
+ from analyze_qvm_air_mode import air
14
+
15
+
16
+ def action(ins,m,cmd,fraction=.5,continuation=False):
17
+ m,p=wall_probe(ins,m,fraction);effects=None;following=None
18
+ if p['stop']==43005:
19
+ def jump(i,m,a,c):
20
+ m,c,r=entry(i,m,c);return m,c,r['return_word'],r
21
+ def codec(i,m,a,c):
22
+ m,r=encode(i,m,[m[a[8]+o]&0xffffffff for o in [0,4,8]],a[8]);return m,c,r['result'],r
23
+ def ev(i,m,a,c):m,r=event(i,m,29913,a);return m,c,0,r
24
+ def anim(i,m,a,c):r=evaluate(i,39525,a[8],m);return r['memory'],c,0,{'request':a[8],'calls':r['calls']}
25
+ m,cmd,effects=execute(ins,43005,43157,m,cmd,LOCAL,{40966:jump,60317:codec,29913:ev,39525:anim})
26
+ before_air=snapshot(m)
27
+ if continuation:m,following=air(ins,m,cmd,'clear',resume_ordinary=True)
28
+ return m,{'probe':p,'effects':effects,'before_air':before_air,'count':m[PS+440],'final':snapshot(m),'air':following}
29
+
30
+
31
+ def main():
32
+ q,raw,h,ins=source();rows=[]
33
+ for meter,mode,up,cont in itertools.product([1499,1500,4000],[0,2],[9,10],[False,True]):
34
+ cmd=(100,0,up);m=memory(raw,h,cmd,0,2048);m.update(table(raw,h));m.update({PS+40:word(-30),PS+440:0,PS+96:word(.6),PS+100:word(.8),34065332:5,PS+184:meter,PS+220:0,34065924:mode,PS+376:17});rows.append(action(ins,m,cmd,.5,cont)[1])
35
+ write_json(Path('docs/research/qvm-wall-action.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual wall prefix/entry/events/codec/animation and optional ordinary-air continuation. Native roots/fractions/slide records and finite configuration supplied; no original executable/full QVM/native physics/rendering executes. Main/environment/scheduler domains remain open.'})
36
+
37
+
38
+ if __name__=='__main__':main()
scripts/qvm_research_support.py CHANGED
@@ -17,3 +17,26 @@ def memory(raw,h,cmd=(100,0,0),plane=1,flags=0):
17
  m=seed(constants(raw,h,[21160,21180,21192,21200,21204,21208,21212,21220,21224,21228]),cmd,plane,flags)
18
  for a in [4,8,12,16]:m.setdefault(0x30000+a,0)
19
  m[0x30000+24]=sum((v&255)<<(8*(i+1)) for i,v in enumerate(cmd));return m
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  m=seed(constants(raw,h,[21160,21180,21192,21200,21204,21208,21212,21220,21224,21228]),cmd,plane,flags)
18
  for a in [4,8,12,16]:m.setdefault(0x30000+a,0)
19
  m[0x30000+24]=sum((v&255)<<(8*(i+1)) for i,v in enumerate(cmd));return m
20
+
21
+
22
+ def execute(ins,start,stop,m,cmd,base,handlers=None):
23
+ """Bounded source calls with actual recovered children at empty-stack boundaries."""
24
+ import math
25
+ from analyze_deferred_auth import trace_slice
26
+ from analyze_bsp_references import trace_fields
27
+ from analyze_qvm_acceleration import FRAME,word,number
28
+ handlers=handlers or {};points=[x['index']+2 for x in ins[start:stop] if x['opcode']=='CALL'];pc=start;trace=[];calls=[];children=[];writes=[];ret=None
29
+ for _ in range(256):
30
+ t=trace_slice(ins,start,stop,m,{},resume_at=pc,stop_targets=[p for p in points if p!=pc],byte_memory={FRAME+25+i:v&255 for i,v in enumerate(cmd)},local_base=base,halt_on_leave=True,capture_stack=True,limit=8192);m=t['memory'];pc=t['stop'];trace+=t['trace'];calls+=t['calls'];writes+=t['byte_writes'];cmd=[t['byte_memory'][FRAME+25+i] for i in range(3)]
31
+ for c in t['calls']:
32
+ if c['target']==-107:value=word(math.sqrt(number(c['args'][8])));r={'input':c['args'][8]&0xffffffff,'root':value}
33
+ else:
34
+ if c['target'] not in handlers:raise ValueError('Unrecovered bounded child '+str(c['target']))
35
+ m,cmd,value,r=handlers[c['target']](ins,m,c['args'],cmd)
36
+ if ins[c['instruction']+1]['opcode']=='STORE4':
37
+ dest=ins[c['instruction']-2];assert dest['opcode']=='LOCAL';m[base+dest['operand']]=value
38
+ children.append({'call':c,'effect':r})
39
+ if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':ret=t['stack'][-1];break
40
+ if pc==stop:break
41
+ else:raise ValueError('Bounded child loop exceeded')
42
+ return m,cmd,{'return':ret,'calls':calls,'children':children,'byte_writes':writes,**trace_fields({'trace':trace},False)}
scripts/test_qvm_wall_action.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest,copy
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,n,f
4
+ from test_qvm_jump_entry import check as check_entry
5
+ from test_qvm_direction_codec import best
6
+ from test_qvm_air_mode import check as check_air
7
+ from qvm_research_support import source,constants
8
+
9
+
10
+ class WallActionTests(unittest.TestCase):
11
+ @classmethod
12
+ def setUpClass(cls):
13
+ cls.r=json.loads(Path('docs/research/qvm-wall-action.json').read_text());q,raw,h,ins=source();cls.c={a:n(v) for a,v in constants(raw,h,[21160,21192,21208,21212,21220,21224]).items()};cls.table=json.loads(Path('docs/research/qvm-direction-codec.json').read_text())['table']
14
+ def test_all24_post_cost_impulse_and_counter_states(self):
15
+ self.assertEqual(len(self.r['probes']),24)
16
+ for p in self.r['probes']:
17
+ e=p['effects']['children'][0]['effect'];check_entry(self,e);s=copy.deepcopy(e['final'])
18
+ if e['return_word']:
19
+ reduced=bool(s['state220']&128 or s['meter']<1500);amount=100 if reduced else 200;s['velocity'][:2]=[word(f(n(v)+f(n(d)*amount))) for v,d in zip(s['velocity'][:2],p['probe']['normal_xy'])]
20
+ if reduced:s['velocity'][2]=word(f(n(s['velocity'][2])-100))
21
+ s['inventory'][-1]=1;s['queue']['events'][1]=86;s['queue']['parameters'][1]=best(p['probe']['normal_xy']+[0],self.table);s['queue']['sequence']=2;s['legs']=26;s['leg_timer']=0
22
+ self.assertEqual(p['before_air'],s);self.assertEqual(p['count'],int(e['return_word']))
23
+ def test_failure_does_not_attach_extra_event_or_animation(self):
24
+ for p in self.r['probes']:
25
+ e=p['effects']['children'][0]['effect'];targets=[c['target'] for c in p['effects']['calls']];self.assertEqual(targets,[40966,60317,29913,39525] if e['return_word'] else [40966])
26
+ def test_actual_codec_event_parameter_and_two_slot_queue(self):
27
+ for p in self.r['probes']:
28
+ if p['effects']['children'][0]['effect']['return_word']:
29
+ self.assertEqual(p['before_air']['queue']['events'],[99,86]);self.assertEqual(p['before_air']['queue']['sequence'],2)
30
+ def test_air_continuation_receives_boosted_live_state(self):
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'])