nmarshall commited on
Commit
3b0aae3
·
1 Parent(s): 537a3ef

qvm: ground

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -260,3 +260,5 @@ Research progress: [QVM view/basis/position tails](research/QVM_VIEW_MOTION.md)
260
  Research progress: [QVM command scale/acceleration](research/QVM_ACCELERATION.md) completes bounded RE-429–431. RE-428/432 retain native sqrt/friction/producers/legal ranges/full mode/collision/runtime/platform work; broad game/rendering milestones remain open.
261
 
262
  Research progress: [QVM friction policies](research/QVM_FRICTION.md) completes bounded RE-433–435. RE-432/436 retain live coefficients/producers/native sqrt/full mode-state/collision/runtime/platform work; broad game/rendering milestones remain open.
 
 
 
260
  Research progress: [QVM command scale/acceleration](research/QVM_ACCELERATION.md) completes bounded RE-429–431. RE-428/432 retain native sqrt/friction/producers/legal ranges/full mode/collision/runtime/platform work; broad game/rendering milestones remain open.
261
 
262
  Research progress: [QVM friction policies](research/QVM_FRICTION.md) completes bounded RE-433–435. RE-432/436 retain live coefficients/producers/native sqrt/full mode-state/collision/runtime/platform work; broad game/rendering milestones remain open.
263
+
264
+ Research progress: [QVM content/ground producers](research/QVM_GROUND.md) completes bounded RE-437–439. RE-436/440 retain native callbacks/helper effects/full collision-state composition/live policy/runtime/platform work; broad game/rendering milestones remain open.
docs/FINDINGS.md CHANGED
@@ -510,3 +510,9 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
510
  **F-185 — Mode friction differs:** helper45461's prefix measures full XYZ, clears all velocity below1, uses1.5 times the source friction word and writes player-state+164=38. This is a separate policy from helper39988; configuration/type meanings and runtime remain unverified. [FRIC-002](research/QVM_FRICTION.md).
511
 
512
  **F-186 — Staged velocity composition:** eighteen fixtures pass evaluated friction velocity into prior scale/acceleration/position slices with the source-image acceleration word8. Earlier example coefficient10/default output remains unchanged. Only velocity is bridged; full state/callee/collision/runtime effects remain omitted. [FRIC-003](research/QVM_FRICTION.md).
 
 
 
 
 
 
 
510
  **F-185 — Mode friction differs:** helper45461's prefix measures full XYZ, clears all velocity below1, uses1.5 times the source friction word and writes player-state+164=38. This is a separate policy from helper39988; configuration/type meanings and runtime remain unverified. [FRIC-002](research/QVM_FRICTION.md).
511
 
512
  **F-186 — Staged velocity composition:** eighteen fixtures pass evaluated friction velocity into prior scale/acceleration/position slices with the source-image acceleration word8. Earlier example coefficient10/default output remains unchanged. Only velocity is bridged; full state/callee/collision/runtime effects remain omitted. [FRIC-003](research/QVM_FRICTION.md).
513
+
514
+ **F-187 — Content-level producer:** helper47217 samples up to three points through frame+228, short-circuits on mask56 misses, retains the first successful raw content word and writes level0–3 at frame+212. Callback/content/height semantics and legal domains remain open. [GROUND-001](research/QVM_GROUND.md).
515
+
516
+ **F-188 — Ground/surface producers:** helper46773 copies a supplied56-byte trace to global35023944; offset44 supplies friction surface word35023988. Ordered recovery/fraction/kick/slope/level branches set walk/plane/ground/flag/timer fields and record helpers. External effects and native collision/runtime remain omitted. [GROUND-002](research/QVM_GROUND.md).
517
+
518
+ **F-189 — Producer/friction connection:** sixteen scalar bridges pass recovered level/walk/surface/PS flags into earlier friction arithmetic with verified initialized coefficients and supplied velocity. Full callback/frame/state/collision composition remains unverified. [GROUND-003](research/QVM_GROUND.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -572,3 +572,5 @@ Research progress: [QVM view/basis/position tails](research/QVM_VIEW_MOTION.md)
572
  Research progress: [QVM command scale/acceleration](research/QVM_ACCELERATION.md) completes bounded RE-429–431. RE-428/432 retain native sqrt/friction/producers/legal ranges/full mode/collision/runtime/platform work; broad game/rendering milestones remain open.
573
 
574
  Research progress: [QVM friction policies](research/QVM_FRICTION.md) completes bounded RE-433–435. RE-432/436 retain live coefficients/producers/native sqrt/full mode-state/collision/runtime/platform work; broad game/rendering milestones remain open.
 
 
 
572
  Research progress: [QVM command scale/acceleration](research/QVM_ACCELERATION.md) completes bounded RE-429–431. RE-428/432 retain native sqrt/friction/producers/legal ranges/full mode/collision/runtime/platform work; broad game/rendering milestones remain open.
573
 
574
  Research progress: [QVM friction policies](research/QVM_FRICTION.md) completes bounded RE-433–435. RE-432/436 retain live coefficients/producers/native sqrt/full mode-state/collision/runtime/platform work; broad game/rendering milestones remain open.
575
+
576
+ Research progress: [QVM content/ground producers](research/QVM_GROUND.md) completes bounded RE-437–439. RE-436/440 retain native callbacks/helper effects/full collision-state composition/live policy/runtime/platform work; broad game/rendering milestones remain open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -319,3 +319,7 @@ Validation: all preceding composition reports regenerated byte-identically, incl
319
  Completed bounded RE-433–435 with `analyze_qvm_friction.py`: verified shipped qagame helper39988/helper45461 prefix, nine file-backed initialized words, 342 shared-friction probes, 24 mode-prefix probes and eighteen velocity-bridge compositions. FRIC-001–003/F-184–186 recover optional planar norm, low-speed X/Y clear with Z retention, gated additive drop terms followed by conditional replacement, all-component ratio scaling, and the separate mode's full norm/whole-vector clear/effective1.5 coefficient/field38 write. Source-image coefficients100/8/4/1/5/3000 and zero-vector words retain exact offsets/bytes; live writers/configuration remain open. Evaluated mode-friction velocity is transferred into partial scale/acceleration/position slices with source-image coefficient8 and matching supplied timestep, while other state/basis/callee/collision effects remain omitted. Sqrt returns come from a supplied finite math model; no full QVM/original executable/native callee/collision/physics system executes. Eight independent tests verify source words/provenance, every shared drop/ratio/vector/gate, low-speed vertical retention, replacement precedence, separate full-norm mode outputs, sqrt requests, pipeline velocity/coefficient/timestep/acceleration/position propagation and scope/boundaries. All 479 tests pass; storage/links/whitespace checks pass. RE-432 remains open; RE-436 tracks live coefficients and flag/level/surface/type producers/legal ranges, native sqrt, other caller policies and full basis/frame/state/callee/collision/mode/step gameplay/macOS/Linux/Rust/Bevy/Solari compatibility; packet/entity/player/snapshot/rendering milestones remain open.
320
 
321
  Validation: all preceding composition reports regenerated byte-identically, including the partial-caller default report. The new friction report reproduced twice byte-identically. Final suite: 479 passing tests. Storage policy/filter setup, documentation links and whitespace checks pass.
 
 
 
 
 
319
  Completed bounded RE-433–435 with `analyze_qvm_friction.py`: verified shipped qagame helper39988/helper45461 prefix, nine file-backed initialized words, 342 shared-friction probes, 24 mode-prefix probes and eighteen velocity-bridge compositions. FRIC-001–003/F-184–186 recover optional planar norm, low-speed X/Y clear with Z retention, gated additive drop terms followed by conditional replacement, all-component ratio scaling, and the separate mode's full norm/whole-vector clear/effective1.5 coefficient/field38 write. Source-image coefficients100/8/4/1/5/3000 and zero-vector words retain exact offsets/bytes; live writers/configuration remain open. Evaluated mode-friction velocity is transferred into partial scale/acceleration/position slices with source-image coefficient8 and matching supplied timestep, while other state/basis/callee/collision effects remain omitted. Sqrt returns come from a supplied finite math model; no full QVM/original executable/native callee/collision/physics system executes. Eight independent tests verify source words/provenance, every shared drop/ratio/vector/gate, low-speed vertical retention, replacement precedence, separate full-norm mode outputs, sqrt requests, pipeline velocity/coefficient/timestep/acceleration/position propagation and scope/boundaries. All 479 tests pass; storage/links/whitespace checks pass. RE-432 remains open; RE-436 tracks live coefficients and flag/level/surface/type producers/legal ranges, native sqrt, other caller policies and full basis/frame/state/callee/collision/mode/step gameplay/macOS/Linux/Rust/Bevy/Solari compatibility; packet/entity/player/snapshot/rendering milestones remain open.
320
 
321
  Validation: all preceding composition reports regenerated byte-identically, including the partial-caller default report. The new friction report reproduced twice byte-identically. Final suite: 479 passing tests. Storage policy/filter setup, documentation links and whitespace checks pass.
322
+
323
+ ## 2026-10-15 — Game-QVM content levels, ground trace and friction-input producers
324
+
325
+ Completed bounded RE-437–439 with `analyze_qvm_ground.py`: verified shipped qagame helpers47217/46773, 28 point-content probes, 168 trace/classification probes and sixteen scalar friction bridges. GROUND-001–003/F-187–189 recover content-mask56 short-circuit/sample coordinates/raw-first contents/level producer, trace callback shape/downward endpoint/full56-byte copy and ordered recovery/fraction/kick/slope/level/landing caller stores/requests. Trace offset44 supplies surface word35023988, and level/walk/surface/PS flags feed the earlier friction arithmetic in scalar bridges. Supplied callback/trace records, recovery returns and omitted landing/touch/ground-lost effects remain explicit; normals/contact legality and native collision/runtime are unverified. Source coefficient bytes are checked. No full QVM/original executable/native callback/collision executes. Eight independent tests verify points/masks/short circuits/arguments, full trace copy/classification/thresholds/helper ordering, scalar propagation/friction results, provenance and scope. All 487 tests pass; the direct friction dependency regenerates unchanged and the new ground report reproduces twice byte-identically. Storage/filter setup, documentation links and whitespace checks pass. No existing analyzer/evaluator code changes. RE-436 remains open; RE-440 tracks native point/trace ABI/collision outputs, content/surface/bounds/height producers, recovery/ground-lost/landing/touch effects, scratch/prior state/full frame/PS/collision-to-friction composition, coefficient writers and gameplay/macOS/Linux/Rust/Bevy/Solari compatibility; packet/entity/player/snapshot/rendering milestones remain open.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -527,3 +527,8 @@ Purpose: turn the supplied installation into an evidence-backed specification of
527
  - [x] RE-434 Recover bounded helper45461 full-norm friction prefix, whole-vector low-speed clear, effective coefficient and state-word write. [FRIC-002](research/QVM_FRICTION.md).
528
  - [x] RE-435 Bridge evaluated mode-friction velocity into partial scale/acceleration/position fixtures with source-image coefficient8 and explicit omitted-state scope. [FRIC-003](research/QVM_FRICTION.md).
529
  - [ ] RE-436 Recover coefficient/global writers/live configuration and ground/level/surface/flag/type producers/legal ranges, native sqrt ABI, other caller friction policy and complete basis/frame/state/callee/collision effects; validate full mode/step/gameplay/macOS/Linux before Rust/Bevy/Solari claims. Continue packet/entity/player/snapshot/rendering work.
 
 
 
 
 
 
527
  - [x] RE-434 Recover bounded helper45461 full-norm friction prefix, whole-vector low-speed clear, effective coefficient and state-word write. [FRIC-002](research/QVM_FRICTION.md).
528
  - [x] RE-435 Bridge evaluated mode-friction velocity into partial scale/acceleration/position fixtures with source-image coefficient8 and explicit omitted-state scope. [FRIC-003](research/QVM_FRICTION.md).
529
  - [ ] RE-436 Recover coefficient/global writers/live configuration and ground/level/surface/flag/type producers/legal ranges, native sqrt ABI, other caller friction policy and complete basis/frame/state/callee/collision effects; validate full mode/step/gameplay/macOS/Linux before Rust/Bevy/Solari claims. Continue packet/entity/player/snapshot/rendering work.
530
+
531
+ - [x] RE-437 Recover bounded helper47217 content callback sample points, mask56 short-circuit/raw contents and level0–3 producer. [GROUND-001](research/QVM_GROUND.md).
532
+ - [x] RE-438 Recover bounded helper46773 trace request/full56-byte copy, ground classification/thresholds/caller stores and recorded recovery/landing/touch requests with supplied trace effects. [GROUND-002](research/QVM_GROUND.md).
533
+ - [x] RE-439 Bridge evaluated content level/ground walk/trace surface/PS flags into prior friction fixtures with independent scalar/arithmetic checks. [GROUND-003](research/QVM_GROUND.md).
534
+ - [ ] RE-440 Recover native point/trace ABI/collision outputs, contents/surface enums and height/bounds producers, recovery/ground-lost/landing/touch effects, scratch/prior state, full frame/PS/collision-to-friction composition and coefficient writers; validate gameplay/macOS/Linux before Rust/Bevy/Solari claims. Continue packet/entity/player/snapshot/rendering work.
docs/research/QVM_FRICTION.md CHANGED
@@ -56,3 +56,5 @@ Only velocity is transferred between the separately evaluated stages. This is no
56
  Eight independent tests verify file bytes/values/provenance, all shared drop/ratio/vector outputs and sqrt requests, low-speed Z retention, replacement rather than addition, full-norm mode behavior/field write, staged velocity/acceleration/position propagation and explicit scope/boundaries. Prior report regeneration checks protect the partial caller's default behavior.
57
 
58
  RE-432 remains open for complete policy/native/runtime recovery. RE-436 must trace coefficient/global writers and live configuration, ground/level/surface/PS-bit/type producers and legal ranges, native sqrt ABI, other callers' friction combinations, complete basis/frame/state/callee transfer and collision/simulation effects, then validate full mode/step/gameplay/macOS/Linux before Rust/Bevy/Solari compatibility claims. Packet/entity/player/snapshot/rendering milestones remain open.
 
 
 
56
  Eight independent tests verify file bytes/values/provenance, all shared drop/ratio/vector outputs and sqrt requests, low-speed Z retention, replacement rather than addition, full-norm mode behavior/field write, staged velocity/acceleration/position propagation and explicit scope/boundaries. Prior report regeneration checks protect the partial caller's default behavior.
57
 
58
  RE-432 remains open for complete policy/native/runtime recovery. RE-436 must trace coefficient/global writers and live configuration, ground/level/surface/PS-bit/type producers and legal ranges, native sqrt ABI, other callers' friction combinations, complete basis/frame/state/callee transfer and collision/simulation effects, then validate full mode/step/gameplay/macOS/Linux before Rust/Bevy/Solari compatibility claims. Packet/entity/player/snapshot/rendering milestones remain open.
59
+
60
+ Follow-up: [ground/content producers](QVM_GROUND.md) connects content sampling and a copied trace to level/walk/surface inputs, then bridges scalar outputs into friction. Native callbacks, omitted helper effects and full collision/state/runtime validation remain open.
docs/research/QVM_GROUND.md ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Game-QVM content levels, ground trace and friction inputs
2
+
3
+ RE-437–439 / F-187–189. [qvm-ground.json](qvm-ground.json) retains shipped qagame helpers47217/46773, 28 point-content probes, 168 ground-classification probes and sixteen scalar friction bridges. Reproduce with `python3 scripts/analyze_qvm_ground.py`; verify with `python3 scripts/test_qvm_ground.py`.
4
+
5
+ This follows [friction policy recovery](QVM_FRICTION.md). Results are bounded synthetic QVM instruction evaluations. No complete QVM, original executable, native callback or collision executes. Point-content return words and the complete 56-byte trace output are supplied. Recovery, ground-lost, landing and event helper effects are omitted; only the recovery Boolean return is supplied explicitly. Trace normals/contact legality are not validated. Scalar bridges do not transfer a complete collision/movement state.
6
+
7
+ ## GROUND-001 — Three content samples and frame level (RE-437)
8
+
9
+ Helper47217 resets frame+208 and frame+212 to zero. It records the callback stored at frame+228 (supplied encoded target-26) with a point pointer and player-state+140 value. Source position comes from player-state+20/+24/+28.
10
+
11
+ Sample heights relative to source Z are:
12
+
13
+ 1. Z-24+1.
14
+ 2. Z-24+trunc_toward_zero((player-state[+164]+24)/2).
15
+ 3. Z-24+(player-state[+164]+24).
16
+
17
+ X/Y remain the source coordinates. The second/third calls occur only when the preceding return word includes mask56. The first accepted return is copied **without masking** to frame+208, and frame+212 becomes1/2/3 according to how many successive samples include mask56. A miss stops further sampling; zero successful samples retain both reset words.
18
+
19
+ 28 probes cover supplied height words-5/20/38/39 and seven content-return patterns, including unrelated bits and 0xffffffff. Independent tests verify exact sampled float words, integer half-height truncation, callback requests, short-circuit counts, raw first-return retention and final level. Water/liquid-like level terminology is provisional until content bits, callback ABI and producers/consumers are confirmed.
20
+
21
+ ## GROUND-002 — Trace request, copy and caller-side classification (RE-438)
22
+
23
+ Helper46773 records the callback stored at frame+224 (supplied target-25) with these explicit arguments:
24
+
25
+ | Slot | Observed value |
26
+ | --- | --- |
27
+ | 8 | Local 56-byte trace destination |
28
+ | 12 | Player-state position pointer (+20) |
29
+ | 16/20 | Frame+184 / frame+196 bounds pointers |
30
+ | 24 | Local endpoint with Z decreased by binary32 0.25 |
31
+ | 28 | Player-state+140 value |
32
+ | 32 | Frame+28 mask |
33
+
34
+ The full supplied trace is copied to global35023944. Its word at offset44 becomes global35023988, connecting the earlier friction surface-word input to this trace producer. Supplied trace entity at offset52 feeds the later ground/entity requests. This establishes the QVM record-copy offsets; the native trace callback and complete native/QVM structure ABI are still open.
35
+
36
+ The caller then applies this priority (all fields refer to the supplied trace/state):
37
+
38
+ | Condition | Caller-side path and stores |
39
+ | --- | --- |
40
+ | Trace word0 nonzero | Record46296(trace); supplied zero result returns immediately |
41
+ | Trace fraction word+8 == binary32 1 | Record46527(); clear globals35023940/35023936; return |
42
+ | Velocity Z >0 and rounded dot(velocity,trace normal) >10 | Toggle player-state+12 bit4096, record39525 animation-code request, set ground word+68=1023, clear both globals |
43
+ | Trace normal Z < binary32 0.7 | Ground+68=1023; global35023940=1, global35023936=0 |
44
+ | Frame level+212 >2 | Same plane/walk stores as the preceding branch |
45
+ | Remaining path | Clear player-state+12 masks16/2; set both globals to1; process landing state and record new ground/entity |
46
+
47
+ The kick-path request selects code26/30 when bit4096 was initially set, or28/32 when initially clear, depending on nonnegative/negative forward byte. The new ground/entity word is the supplied trace entity, eight in these fixtures.
48
+
49
+ On the remaining path, initial player-state+12 bit128 is cleared and player-state+16 reset to0. If prior ground word+68 was1023, it records helper45912(new entity), then sets the timer word to250 only when saved vertical word35024024 is strictly below-200. It assigns the new ground word and records helper39253(new entity). No landing/event helper effects are applied.
50
+
51
+ 168 probes vary allsolid/recovery, fraction, normal Z, upward velocity, level, previous ground, PS flags, saved fall velocity and signed forward direction. They cover the exact0.7 and-200 thresholds and strict dot>10 condition. Independent oracles check full trace copy, callback shape, branch priority, caller stores and recorded call ordering.
52
+
53
+ Initial global sentinels11/22 demonstrate when this caller does not assign them, such as failed recovery; they are not a claim that real movement reaches such values. The earlier scratch-reset and external helper effects are not composed. Successful recovery fixtures continue with an unchanged supplied record, which is conditional on the omitted recovery effects.
54
+
55
+ ## GROUND-003 — Scalar producer-to-friction bridge (RE-439)
56
+
57
+ Sixteen fixtures evaluate content samples, pass the resulting level into ground classification, then pass the resulting walk/global35023936, trace-derived surface/global35023988, level/frame+212 and PS flags into the previously recovered friction helper. They combine levels0–3, supplied normal Z0.5/1 and surface words0/2.
58
+
59
+ This connects concrete producer offsets to earlier friction gates: the frame level comes from successive content-mask hits, the walk input comes from ground classification and the surface input comes from the copied trace's offset44. The friction fixtures retain independently supplied velocity(200,0,0) and verified initialized coefficient words; only these scalar states are bridged.
60
+
61
+ Tests use the independent friction arithmetic oracle to verify the resulting drop/ratio/vector and exact transferred values. Point/trace callbacks, real coefficient writers, complete frame/PS changes, other helper effects and collisions remain omitted. Full simulation/gameplay equivalence is not established.
62
+
63
+ ## Validation and next tasks
64
+
65
+ Eight tests independently verify sampling/masks/points/requests, trace arguments/endpoints/full copy, classification/stores/helper ordering, strict thresholds, scalar friction propagation, source/coefficient bytes and explicit scope. The full suite runs; the direct friction dependency and new ground report are regenerated, with the new report checked twice for identical bytes. No existing analyzer/evaluator code changes in this batch.
66
+
67
+ RE-436 remains open for complete policy/producers/runtime work. RE-440 must recover native point/trace callback ABI and collision results, content/surface bit meanings and bounds/height producers, recovery/ground-lost/landing/touch helper effects, actual scratch reset and prior state, full frame/PS/collision-to-friction composition, coefficient writers and gameplay/macOS/Linux before Rust/Bevy/Solari compatibility claims. Packet/entity/player/snapshot/rendering milestones remain open.
docs/research/README.md CHANGED
@@ -173,3 +173,5 @@ The extension collector adds five focused tests for native tail calls, command-r
173
  [QVM command scaling and acceleration](QVM_ACCELERATION.md) adds RE-429–431. Reproduce with `python3 scripts/analyze_qvm_acceleration.py`; check with `python3 scripts/test_qvm_acceleration.py`. Sqrt, basis and post-friction inputs are supplied; complete mode/native/runtime effects remain open.
174
 
175
  [QVM friction and velocity composition](QVM_FRICTION.md) adds RE-433–435. Reproduce with `python3 scripts/analyze_qvm_friction.py`; check with `python3 scripts/test_qvm_friction.py`. Constants are initialized-image snapshots; native sqrt, live policy and full state/collision/runtime effects remain open.
 
 
 
173
  [QVM command scaling and acceleration](QVM_ACCELERATION.md) adds RE-429–431. Reproduce with `python3 scripts/analyze_qvm_acceleration.py`; check with `python3 scripts/test_qvm_acceleration.py`. Sqrt, basis and post-friction inputs are supplied; complete mode/native/runtime effects remain open.
174
 
175
  [QVM friction and velocity composition](QVM_FRICTION.md) adds RE-433–435. Reproduce with `python3 scripts/analyze_qvm_friction.py`; check with `python3 scripts/test_qvm_friction.py`. Constants are initialized-image snapshots; native sqrt, live policy and full state/collision/runtime effects remain open.
176
+
177
+ [QVM content sampling, ground classification and friction inputs](QVM_GROUND.md) adds RE-437–439. Reproduce with `python3 scripts/analyze_qvm_ground.py`; check with `python3 scripts/test_qvm_ground.py`. Callback results are supplied and only scalar states bridge into friction; full collision/runtime work remains open.
docs/research/qvm-ground.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_ground.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Bounded content sampling/ground classification and scalar friction bridge."""
3
+ import itertools
4
+ import json
5
+ import struct
6
+ from pathlib import Path
7
+ from analyze_bsp_references import trace_fields
8
+ from analyze_deferred_auth import trace_slice
9
+ from analyze_qvm import decode,write_json
10
+ from analyze_qvm_acceleration import FRAME,PS,word,number
11
+ from analyze_qvm_friction import friction_probe
12
+ from analyze_vm_extensions import verified
13
+
14
+ POINT_LOCAL=0x45000000
15
+ GROUND_LOCAL=0x46000000
16
+
17
+
18
+ def contents_probe(ins,height,returns):
19
+ m={35024032:FRAME,FRAME:PS,PS+140:7,PS+164:height,PS+20:word(100),PS+24:word(200),PS+28:word(300),FRAME+208:99,FRAME+212:99,FRAME+228:-26};pc=None;trace=[];calls=[];points=[];stops=[47279,47353,47404]
20
+ while True:
21
+ boundaries=[x for x in stops if pc is None or x>pc];t=trace_slice(ins,47218,47420,m,{},stop_targets=boundaries,resume_at=pc,call_results={47277:returns[0],47351:returns[1],47402:returns[2]},local_base=POINT_LOCAL,limit=512);m=t['memory'];trace+=t['trace'];calls+=t['calls']
22
+ if t['calls']:points.append([m[POINT_LOCAL+16+i*4]&0xffffffff for i in range(3)])
23
+ if t.get('stop',47420)==47420:break
24
+ pc=t['stop']
25
+ return {'height_word':height,'supplied_contents_words':returns,'sample_point_float_words':points,'calls':calls,'result_contents_word':m[FRAME+208]&0xffffffff,'result_level_word':m[FRAME+212],**trace_fields({'trace':trace},False)}
26
+
27
+
28
+ def ground_probe(ins,allsolid=0,recovered=1,fraction=.5,normal_z=1,velocity_z=0,level=0,oldground=7,psflags=0,surface=0,previous_z=0,forward=1):
29
+ record=[allsolid,0,word(fraction),word(100),word(200),word(299.75),0,0,word(normal_z),0,0,surface,0,8];m={35024032:FRAME,FRAME:PS,PS+20:word(100),PS+24:word(200),PS+28:word(300),PS+32:0,PS+36:0,PS+40:word(velocity_z),PS+140:7,PS+68:oldground,PS+12:psflags,PS+16:99,FRAME+28:0x2010001,FRAME+224:-25,FRAME+32:0,FRAME+212:level,35023940:11,35023936:22,35024024:word(previous_z)}
30
+ for i,w in enumerate(record):m[GROUND_LOCAL+36+i*4]=w
31
+ # Trace output words are supplied before the callback boundary; its actual
32
+ # implementation/pointer conversion/physics effects are not evaluated.
33
+ pre=trace_slice(ins,46774,47215,m,{},stop_targets=[46847],local_base=GROUND_LOCAL,limit=512);m=pre['memory'];point=[m[GROUND_LOCAL+92+i*4]&0xffffffff for i in range(3)];post=trace_slice(ins,46774,47215,m,{},resume_at=46847,call_results={46858:recovered},byte_memory={FRAME+25:forward&255},local_base=GROUND_LOCAL,limit=1024);m=post['memory'];p={'allsolid_word':allsolid,'supplied_recovery_word':recovered,'fraction_float_word':word(fraction),'normal_z_float_word':word(normal_z),'velocity_z_float_word':word(velocity_z),'level_word':level,'old_ground_word':oldground,'initial_ps_flags_word':psflags,'surface_word':surface,'previous_z_float_word':word(previous_z),'forward_word':forward,'trace_record_words':record,'trace_request':pre['calls'],'trace_end_float_words':point,'copied_trace_words':[m[35023944+i*4]&0xffffffff for i in range(14)],'classification_calls':post['calls'],'result_plane_word':m[35023940],'result_walk_word':m[35023936],'result_surface_word':m[35023988],'result_ground_word':m[PS+68],'result_ps_flags_word':m[PS+12]&0xffffffff,'result_timer_word':m[PS+16],**trace_fields({'trace':pre['trace']+post['trace']},False)};return p
34
+
35
+
36
+ def bridge_probe(ins,constants,returns,slope,surface):
37
+ point=contents_probe(ins,38,returns);ground=ground_probe(ins,level=point['result_level_word'],normal_z=slope,surface=surface);friction=friction_probe(ins,constants,(200,0,0),grounded=ground['result_walk_word'],level=point['result_level_word'],surface=ground['result_surface_word'],psflags=ground['result_ps_flags_word']);return {'contents_probe':point,'ground_probe':ground,'friction_probe':friction}
38
+
39
+
40
+ def main():
41
+ r=json.loads(Path('docs/research/qvm/qagame.json').read_text());data=verified(Path(r['source']['member']['output']).read_bytes(),r['sha256']);h,ins=decode(data);patterns=[(0,8,8),(8,0,8),(8,8,0),(8,8,8),(57,16,32),(1,56,56),(0xffffffff,0xffffffff,0xffffffff)];grounds=[ground_probe(ins,allsolid=a,recovered=ok,fraction=frac,normal_z=z,velocity_z=v,level=l) for a,ok,frac,z,v,l in itertools.product([0,1],[0,1],[.5,1],[.5,.7,1],[0,20],[0,3])]
42
+ grounds += [ground_probe(ins,oldground=old,psflags=flags,previous_z=z,forward=fwd,velocity_z=v) for old,flags,z,fwd,v in itertools.product([7,1023],[0,146,4096],[-199,-200,-201],[-1,1],[0,20])];constants={a:struct.unpack_from('<I',data,h['data_offset']+a)[0] for a in [21160,21200,21208,21212,21220,21224,21348,21352,21356]};out={'source':r['source'],'sha256':r['sha256'],'contents_instructions':ins[47217:47422],'ground_instructions':ins[46773:47217],'contents_probes':[contents_probe(ins,*v) for v in itertools.product([-5,20,38,39],patterns)],'ground_probes':grounds,'bridge_probes':[bridge_probe(ins,constants,*v) for v in itertools.product(patterns[:4],[.5,1],[0,2])],'coefficient_words':constants,'limitations':'Bounded synthetic shipped-QVM slices only; no full QVM/original process/native callback/collision executes. Point-content return words and complete56-byte trace output are supplied. Trace callback only records requests; recovery/ground-lost/landing/event helper results/effects are supplied or omitted. Scalar bridge passes evaluated level/walk/surface/PS flags into prior friction fixtures with independently supplied velocity/image coefficients, not full frame/state/physics composition. Semantic field/bit/contents names, valid bounds/pointers/live configuration and runtime/platform parity remain open.'};write_json(Path('docs/research/qvm-ground.json'),out);print('Recovered content levels ground trace classification and scalar friction bridge')
43
+
44
+
45
+ if __name__=='__main__':main()
scripts/test_qvm_ground.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Independent point/trace classification and producer-to-friction oracles."""
3
+ import hashlib
4
+ import json
5
+ from pathlib import Path
6
+ import struct
7
+ import unittest
8
+ from test_qvm_friction import friction_oracle
9
+
10
+
11
+ def word(v):return struct.unpack('<I',struct.pack('<f',v))[0]
12
+ def n(v):return struct.unpack('<f',struct.pack('<I',v&0xffffffff))[0]
13
+ def f(v):return n(word(v))
14
+
15
+ def ground_oracle(p):
16
+ flags=p['initial_ps_flags_word'];ground=p['old_ground_word'];timer=99;plane,walk=11,22;calls=[]
17
+ if p['allsolid_word']:
18
+ calls.append((46296,{'8':0x46000024}))
19
+ if not p['supplied_recovery_word']:return plane,walk,ground,flags,timer,calls
20
+ if n(p['fraction_float_word'])==1:return 0,0,ground,flags,timer,calls+[(46527,{})]
21
+ if n(p['velocity_z_float_word'])>0 and f(n(p['velocity_z_float_word'])*n(p['normal_z_float_word']))>10:
22
+ was=bool(flags&4096);flags^=4096;anim=(26 if was else 28) if p['forward_word']>=0 else (30 if was else 32);return 0,0,1023,flags,timer,calls+[(39525,{'8':anim})]
23
+ if n(p['normal_z_float_word'])<n(1060320051) or p['level_word']>2:return 1,0,1023,flags,timer,calls
24
+ flags&=~18
25
+ if flags&128:flags&=~128;timer=0
26
+ if ground==1023:
27
+ calls.append((45912,{'8':8}))
28
+ if n(p['previous_z_float_word'])<-200:timer=250
29
+ calls.append((39253,{'8':8}));return 1,1,8,flags,timer,calls
30
+
31
+
32
+ class QvmGroundTests(unittest.TestCase):
33
+ @classmethod
34
+ def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-ground.json').read_text())
35
+
36
+ def test_content_level_mask_short_circuit_and_first_raw_word(self):
37
+ self.assertEqual(len(self.r['contents_probes']),28)
38
+ for p in self.r['contents_probes']:
39
+ level=0
40
+ for v in p['supplied_contents_words']:
41
+ if not v&56:break
42
+ level+=1
43
+ self.assertEqual(p['result_level_word'],level);self.assertEqual(p['result_contents_word'],p['supplied_contents_words'][0]&0xffffffff if level else 0);self.assertEqual(len(p['calls']),min(level+1,3));self.assertTrue(all(c['target']==-26 and c['args']=={'8':0x45000010,'12':7} for c in p['calls']))
44
+
45
+ def test_content_sample_point_coordinates_and_odd_height_truncation(self):
46
+ for p in self.r['contents_probes']:
47
+ height=p['height_word'];zs=[277,276+int((height+24)/2),300+height];expected=[[word(100),word(200),word(z)] for z in zs[:len(p['calls'])]];self.assertEqual(p['sample_point_float_words'],expected)
48
+
49
+ def test_trace_callback_arguments_endpoint_and_full_copy(self):
50
+ self.assertEqual(len(self.r['ground_probes']),168)
51
+ for p in self.r['ground_probes']:
52
+ self.assertEqual(p['trace_end_float_words'],[word(100),word(200),word(299.75)]);self.assertEqual(p['trace_request'],[{'instruction':46845,'target':-25,'args':{'8':0x46000024,'12':0x10014,'16':0x300b8,'20':0x300c4,'24':0x4600005c,'28':7,'32':0x2010001}}]);self.assertEqual(p['copied_trace_words'],p['trace_record_words']);self.assertEqual(p['result_surface_word'],p['trace_record_words'][11])
53
+
54
+ def test_classification_branch_priority_words_and_helper_requests(self):
55
+ for p in self.r['ground_probes']:
56
+ plane,walk,ground,flags,timer,calls=ground_oracle(p);self.assertEqual([p['result_plane_word'],p['result_walk_word'],p['result_ground_word'],p['result_ps_flags_word'],p['result_timer_word']],[plane,walk,ground,flags,timer]);self.assertEqual([(c['target'],c['args']) for c in p['classification_calls']],calls)
57
+
58
+ def test_strict_slope_kick_and_landing_thresholds(self):
59
+ rows=self.r['ground_probes'];flat=next(p for p in rows if p['allsolid_word']==0 and n(p['fraction_float_word'])==.5 and n(p['normal_z_float_word'])==n(1060320051) and n(p['velocity_z_float_word'])==0 and p['level_word']==0);self.assertEqual(flat['result_walk_word'],1)
60
+ for z,timer in [(-199,99),(-200,99),(-201,250)]:
61
+ p=next(p for p in rows if p['old_ground_word']==1023 and p['initial_ps_flags_word']==0 and n(p['previous_z_float_word'])==z and n(p['velocity_z_float_word'])==0);self.assertEqual(p['result_timer_word'],timer)
62
+
63
+ def test_scalar_bridge_outputs_drive_friction_oracle(self):
64
+ self.assertEqual(len(self.r['bridge_probes']),16);constants={int(k):n(v) for k,v in self.r['coefficient_words'].items()}
65
+ for p in self.r['bridge_probes']:
66
+ point,ground,friction=p['contents_probe'],p['ground_probe'],p['friction_probe'];self.assertEqual(ground['level_word'],point['result_level_word']);self.assertEqual(friction['level_word'],point['result_level_word']);self.assertEqual(friction['grounded_word'],ground['result_walk_word']);self.assertEqual(friction['surface_word'],ground['result_surface_word']);self.assertEqual(friction['ps_flags_word'],ground['result_ps_flags_word']);root,drop,ratio,result=friction_oracle(friction,constants);self.assertEqual(friction['supplied_sqrt_word'],root);self.assertEqual(friction['drop_float_word'],drop);self.assertEqual(friction['ratio_float_word'],ratio);self.assertEqual(friction['result_velocity_float_words'],result)
67
+
68
+ def test_source_identity_and_retained_helper_partitions(self):
69
+ q=json.loads(Path('docs/research/qvm/qagame.json').read_text());raw=Path(q['source']['member']['output']).read_bytes();self.assertEqual(hashlib.sha256(raw).hexdigest(),self.r['sha256']);self.assertEqual(q['source'],self.r['source']);self.assertEqual(self.r['contents_instructions'][0]['index'],47217);self.assertEqual(self.r['ground_instructions'][-1]['index'],47216)
70
+ data_offset=struct.unpack_from('<i',raw,16)[0]
71
+ for address,value in self.r['coefficient_words'].items():self.assertEqual(struct.unpack_from('<I',raw,data_offset+int(address))[0],value)
72
+
73
+ def test_unknown_external_effects_and_scalar_scope_are_explicit(self):
74
+ self.assertIn('complete56-byte trace output are supplied',self.r['limitations']);self.assertIn('not full frame/state/physics composition',self.r['limitations'])
75
+
76
+
77
+ if __name__=='__main__':unittest.main()