urt-rs / docs /research /QVM_FRICTION.md
nmarshall's picture
qvm: ground
3b0aae3
|
Raw History Blame Contribute Delete
7.04 kB

Game-QVM friction policies and velocity composition

RE-433–435 / F-184–186. qvm-friction.json retains helper39988, the friction prefix of helper45461, nine file-backed initialized words, 342 shared-friction probes, 24 mode-prefix probes and eighteen staged caller compositions. Reproduce with python3 scripts/analyze_qvm_friction.py; verify with python3 scripts/test_qvm_friction.py.

This follows command scale and acceleration. Results are bounded synthetic instruction evaluations; no complete QVM, original executable, native callee or collision/physics system executes. Square-root returns are supplied from ordinary finite math. The staged pipeline transfers only evaluated friction velocity into the previous partial caller. It supplies the identity basis, command/button/meter and timestep, and omits other state/callee/frame/collision effects.

FRIC-001 — Initialized words and shared helper39988 (RE-433)

The collector verifies source-image bytes, file offsets and VM addresses for these words. These are an initialized image snapshot, not a proof of immutable constants or live configuration:

VM address Binary32 value Observed use in these slices
21160 100 Minimum control speed in ground-like drop
21200 8 Acceleration coefficient supplied to the new pipeline
21208 4 Ground-like/shared friction coefficient
21212 1 Frame-level-dependent drop coefficient
21220 5 Type/flag-dependent drop coefficient
21224 3000 Player-state flag-mask12 drop coefficient
21348/21352/21356 0/0/0 Vector copied by the mode-specific low-speed branch

Helper39988 copies velocity from player-state+32/+36/+40 into a local vector. Nonzero global35023936 removes Z only from the measured vector, before requesting its length from target-107. The original velocity vector is not projected to a plane at this point.

If measured speed <1, it clears original X/Y velocity and returns, retaining original Z. Otherwise it accumulates drop with operation-level binary32 rounding. Ground/level/surface terminology below is provisional pending producers and consumers.

Predicate Term added to drop
Frame+212 <=1, global35023936 nonzero, global35023988 bit2 clear, player-state+12 bit64 clear max(speed,word21160) * word21208 * dt
Frame+212 nonzero speed * word21212 * float(frame+212) * dt
Player-state+12 mask12 nonzero speed * word21224 * dt
Type at player-state+4 ==2 or player-state+220 bit2048 speed * word21220 * dt

After those additions, player-state+104 bit1 replaces accumulated drop with dt *1000 * binary32(0.15); it does not add another term. The slice then computes ratio = max(speed-drop,0)/speed and scales all three original velocity components by the ratio. Thus a planar measured speed can determine scaling of original vertical velocity as well; the low-speed return is the separate exception described above.

342 probes vary supplied vectors, norm mode, frame levels, surface/PS bits, types, special flags, replacement flag and timesteps0/0.016/0.5. Independent rounded formulas verify measured sqrt requests, every drop/ratio/final vector, low-horizontal-speed vertical retention and replacement behavior. Numeric fields/flags, negative or unusual configuration ranges, callbacks and runtime behavior remain open.

FRIC-002 — Mode-specific helper45461 prefix (RE-434)

The prefix45462–45647 first writes38 to player-state+164. It measures full XYZ speed, without the shared helper's optional planar measurement. A speed below1 copies the file-backed zero vector into all three velocity components, even when supplied dt is zero.

Other paths use an effective coefficient of word21208 *1.5 (six under this image snapshot). Drop is max(speed,word21160) * effective_coefficient *dt, with rounding after each operation. It scales velocity by max(speed-drop,0)/speed.

This differs from shared helper39988 in norm selection, low-speed Z treatment and coefficient, and does not include its other drop terms/replacement branch. The two policies must not be merged into a single inferred friction rule.

24 probes cover tiny/exact-one/mixed/high/signed vectors with three timesteps. Independent full-norm and rounded drop/ratio formulas verify all velocity words, the+164 write and the square-root request. Earlier configuration/lifecycle and the field38 meaning remain unverified.

FRIC-003 — Velocity-only bridge into the partial caller (RE-435)

Eighteen compositions evaluate the mode-specific friction prefix, then transfer its three velocity words into the prior helper45461 partial caller. That caller evaluates command scaling, wish-vector construction/normalization, helper40275 acceleration and unconditional position-tail updates. Source-image coefficient8 replaces the earlier report's explicitly supplied example coefficient10 in these new fixtures; the previous report retains its original defaults and scope.

The new fixtures cover three initial velocity vectors, zero/axis/diagonal commands and dt0.016/0.5. They use button256 and supplied meter11, identity basis and initial position10/20/30. Larger timestep probes are synthetic arithmetic cases, not asserted reachable within the recovered scheduler caps. Tests independently verify friction output, exact velocity handoff, coefficient/timestep propagation, acceleration and final position words.

Only velocity is transferred between the separately evaluated stages. This is not a full helper45461 call-frame composition: its other state words, earlier/callee effects, native sqrt/basis generation, collision and runtime context remain omitted. The shared partial-caller helper now accepts coefficient and dt parameters with unchanged defaults, preserving earlier report output.

Validation and remaining work

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.

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.

Follow-up: ground/content producers 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.