Download docs/research/QVM_CLIENT_TIMER_BATCH.md from nmarshall/urt-rs: direct link, hf CLI and curl.
- Browser
- Download file 8.79 kB
-
https://huggingface.co/nmarshall/urt-rs/resolve/main/docs/research/QVM_CLIENT_TIMER_BATCH.md
- Command line
-
hf download hf://nmarshall/urt-rs/docs/research/QVM_CLIENT_TIMER_BATCH.md
-
curl -L -o QVM_CLIENT_TIMER_BATCH.md https://huggingface.co/nmarshall/urt-rs/resolve/main/docs/research/QVM_CLIENT_TIMER_BATCH.md
Client timer body and caller preparation: RE-964–973
Ten tasks recover five source/Rust contracts across 760 paired fixtures. They extend the filter-command/frame-prefix batch through the complete persistent-state body of150692 and the timing-preparation prefix of its caller154089. Each task has its own commit and focused cargo xtask checks. Native time replies are supplied, and damage effects remain captured requests against supplied health.
| Tasks | Evidence | Paired fixtures |
|---|---|---|
| RE-964 / RE-965 | Original deadline fragments / Rust fragments | 144 |
| RE-966 / RE-967 | Original phase loop / Rust loop | 288 |
| RE-968 / RE-969 | Original countdown/recovery / Rust recovery | 216 |
| RE-970 / RE-971 | Original complete timer body / Rust composition | 16 |
| RE-972 / RE-973 | Original caller preparation / Rust preparation | 96 |
Deadline and phase-loop findings
The first contract executes two explicit fragments:150791..150810 before the loop, and151085..151131 after it. Entity cooldown seconds multiply by1000 and add to a timestamp using word wrap before signed comparison with the game tick. Exact equality retains the entity flag; strictly older values clear it. The terminal fragment clears client mask2 only after a strict deadline, preserves unrelated bits and timestamp words, and adds milliseconds to a wrapping total counter. These fragments are kept separate in the Rust API so the complete timer can place them around the loop in source order.
The100ms loop consumes signed residual values while they are at least100. Each iteration increments a phase word with wrap and computes signed remainder using a table indexed by rate-1. Rates1..5 select9,4,3,2,1. Rate0 reads the preceding word, whose raw value is1120403456, also the bit pattern for100.0f32. That word is used as an integer divisor. The port preserves the alias; unsupported rate/table domains reject explicitly.
Flag256, positive supplied health and phase zero cause a damage request. The source requests target entity, owner as both inflictor and attacker, null direction/point, amount1, flags0, means word23 and the entity weapon word. These arguments are projected from actual211239 calls. The callback effect is captured, so repeated loop decisions continue to use supplied health. Actual health/death effects and feedback into the loop remain open.
Float countdown and recovery ordering
The full loop contract adds flags512/256/128, repeated f32 subtraction of0.1 and associated status/rate resets. Initially nonpositive countdown with flag256 clears that flag, sets rate0 and stores zero. Positive countdown subtracts one f32 step per iteration; crossing zero also clears flag256 and resets rate/countdown.
A positive countdown that crosses zero jumps to the loop boundary before secondary flag128/status cleanup. That cleanup can occur on a later iteration. An initially nonpositive countdown can reach it in the same iteration. Clearing flag128 also clears status mask1. Rate reset0 changes the divisor for following iterations through the preceding-word alias. Source fixtures verify exact float words, phase progression and unrelated bits. Gameplay names and ownership for these raw status fields still need caller/structure evidence.
Rust supports finite countdowns and bounded residual/rate domains, stages unsupported inputs without partial mutation, and retains the original ordering. The earlier flag512-disabled cases remain regressions of the expanded API.
Complete timer composition
The16 whole-body probes execute150692 through its void-return boundary at151131. Actual65613 horizontal squared-motion and252067/251995 expiry children execute; native time is supplied and damage211239 remains captured. The persistent write set covers activity and entity-bit copies, the shared residual, entity cooldown, loop flags/status/rate/phase/countdown, terminal flags and elapsed total, plus all4096 filter rows through table-wide checksums.
The residual is one source word: prefix milliseconds accumulate into it before100ms consumption. Rust models that ownership once and composes prefix/expiry, pre-loop deadline, the full tick loop and terminal tail in order. Time acquisition precedes damage requests. The contract retains count-zero expiry, unchanged velocity/last-motion words, duplicate flag updates and wrapping totals. Typed errors roll back the staged table and client state together.
This recovers the complete timer body's finite persistent-state behavior under the stated child boundaries. It does not establish actual native clock acquisition, damage/health execution, network behavior or the complete caller154089.
Caller preparation
The direct timer call is at155714 inside154089. This batch executes only the caller prefix154090..154210, with155716 as a separate early-return boundary. It does not jump over or claim the intervening processing before timer dispatch.
The prefix requires connection word468 to equal2. It then copies the game tick and original command timestamp into client words6172/6176, clamps command time sequentially against tick+200 and tick-1000 using signed wrapping arithmetic, and computes a delta from the current command-time word. A delta below1 exits unless word3108 equals2. A proceeding delta above200 caps at200.
If quantization word712 is nonzero, the command timestamp then rounds using (command+7)/8*8 with original signed arithmetic. The delta is not recomputed after rounding. Source cases demonstrate a rounded timestamp of10000 with a retained delta9, and a permitted negative delta through the word3108 exception. Rust preserves disconnected state, original timestamp copies, exact early-gate mutations and sequential bounds under wrap. Semantic field ownership and the remaining caller paths are still open.
Validation
Each task ran its focused cargo xtask test-group before its commit: qvm/rust-client-timer-terminal, qvm/rust-client-timer-ticks, qvm/rust-client-timer-recovery, qvm/rust-client-timer-complete and qvm/rust-client-timer-prepare. Selected reports regenerated twice identically. Independent word arithmetic, loop/flag and composition expectations check original probes; Rust reports compare every projected field against its source report and record its SHA256.
Rust regressions also cover signed cooldown wrap, strict equalities, phase wrap/remainder, exact damage arguments, preceding-word rate alias, delayed cleanup, unsupported float/rate rollback, whole-timer state/table rollback, disconnected caller state, nonpositive-delta exception and post-delta rounding. Dependency-selection regressions include all five source/Rust pairs and shared timer/command/loading/lifecycle/native-policy/formatter inputs, including scoped gameplay test-count metadata. Python uses the flake-declared Nix runtime throughout, including Git hooks. Original assets are unchanged. The single cargo xtask test-full --since c1e91e2e run after task ten passed: 1,878 Python tests, 270 Rust tests (assets10, gameplay230, xtask30), 106 deterministic report producers, storage policy, links across 546 documentation files and whitespace guards. Regeneration left no changes. Focused dependency-selection regression also passed. Validation notes are amended into task ten, preserving ten commits for the batch.
Historical next work after RE-973
- Recover caller154089 after154210 through155714, including all alternate exits, callbacks and any later changes to timing/state before timer dispatch.
- Resolve211239 damage effects and health/death feedback inside the loop, plus field/status ownership and the complete source rate/countdown lifecycle.
- Extend timing-prefix wrap/quantization domains, invalid rate/table provenance, nonfinite floats and larger residual budgets with source-backed probes.
- Recover initialization3877 around loader252933, table reset/ownership ordering, native time ABI/calendar rollover and actual expiry/frame cadence.
- Attach real time/damage/file/userinfo/queued-command/network adapters and validate operation order/failure behavior on macOS/Linux.
- Continue bot setup125185, userinfo171668, ranking5864, native collision, respawn/intermission/events/scoreboard, asset conversion and Rust/Bevy/Solari runtime acceptance.
Follow-up: RE-974–983 pre-movement processing findings and current next work.