Skip to content

Batch 51 · Measured keyboard movement compatibility

2026-10-27. Starting HEAD 4b3fba48; implementation c19ef425, followed by this separate evidence commit. This supplies the measured keyboard boundary needed before extracting Player movement. Production Player, Entity, AbilityHolder, scenes and authored input settings are unchanged. The shared scene's prepared character still does not move or fight.

What changed and why

The raw command vector loses information: both left/right held and neither held both produce zero. Actual legacy GetAxis keeps its previous value when opposing directions are held. A consumer using only RawMove would change movement. PlayerCommandFrame now also exposes NegativeMove/PositiveMove from the individually resolved unprocessed controls. Existing raw differences, button edges and Reward/Blocked behavior remain compatible; those non-gameplay contexts do not expose gameplay pressures. No binding IDs, pairing rules or saved data change.

KeyboardMovementFilter reproduces the recorded default keyboard axes. It receives the clock explicitly, keeps independent horizontal/vertical state, applies rates 5/3 and preserves the measured order of acceleration and reversal gravity. Its clock is scaled delta: state freezes at timeScale 0 and held input continues on resume. Nonzero smoothed values below .001 remain observable. The adapter does not normalize movement, pair devices, own pause, move the actor or implement analog processing. Reset is an explicit utility; the checks do not establish a complete actor/session reset policy. Sampling continuity while no actor exists, held keys at first activation, focus loss and device reassignment remain integration questions. Preserve input identity across actor retry rather than blindly resetting its history.

Original observation evidence

The new Editor-only LegacyMovementCapture samples actual Unity Input.GetAxis/GetAxisRaw and calls the unchanged production Player.Movement. It uses the real prefab, fixed movement 2.8/dash-speed 5, explicit camera/material and an empty scene; all legacy behaviours and physics simulation are disabled. Selected stun/dash phases supply those flags, with dash velocity 7/8. This observes method behavior, not an executed dash ability, collision or movement feel. In-memory input binding lists are scoped/restored; no normal game/bootstrap/save/online services are initialized.

A guarded XTest sequence targets only the active owned Editor window, accepting its legitimate GTK focus descendant. All 32 requested phases complete, plus initial neutral: 8,220 samples, capture process exit0 in 57.165s. Default WASD press/release, horizontal opposed holds in both orders, reversal, diagonals, stun, supplied dash state and scaled pause/resume are recorded. All SDK raw keyboard differences agree with legacy raw axes and every observation reports the focused GameView. The target-frame-rate setting did not fix Editor cadence; per-frame captured deltas are used. This is not physical arrow/remapped-key, analog, native-player or Windows evidence.

LegacyMovementReference.json pins original source/axis hashes and retains 2, 967 state boundaries. Only interiors of consecutive identical input/observed-state runs are omitted; the full private trace remains. The reference's SHA-256 is 1fd0dfdc02a8f5064f2dc117e650fee6959b733cbf3e76b75eb2f06cc709e18e. The original Player file matches its captured hash after the implementation. Do not regenerate this reference to accept a changed motor.

The observed method outputs include normalized full-speed velocity with Speed below .1, stale Speed/last-input during stun, input-axis advancement while stunned, and preserved external dash velocity after releasing movement. The next motor comparison must use these original outputs. The current new filter comparison establishes axis equivalence only.

Verification and trial dispositions

Final MovementInputChecks.RunBatch51: 9/9 groups, exit0, 30.250s. The SDK-backed replay exactly equals every retained original horizontal/vertical value, using separate held directions and the recorded scaled delta. Other checks cover original provenance/counts, opposition versus release, paused/held resume, independent state/explicit reset, blocked/reward isolation, invalid clock rejection, unchanged unprocessed simulated-gamepad values and retained motor observation cases. Simulated gamepad pressures do not establish legacy analog dead-zone or hardware equivalence.

RunBatch51SessionRegression runs the unchanged original session checks under scoped Localization toolbar restoration: 8/8, exit0, 29.911s. It retains existing device isolation, keyboard layouts/edges, context handoff, reconnect, binding overrides, run/reload and disposal coverage. Both accepted logs contain no exception heading. Toolbar existence/value, SDK settings and temporary input users are restored. No Linux native build/player was rerun: production input/movement consumers are unchanged; batch50 retains its existing native two-player smoke evidence. The new filter has no production actor consumer yet.

Early capture helpers rejected GTK's child focus, checked readiness before a first sample or used a non-atomic phase request/short acknowledgment wait. These trials are excluded. The accepted helper checks active client plus descendant focus, first-sample readiness and atomic acknowledged requests. An early GUI launch also inherited the unavailable Windows build profile; the accepted capture explicitly selects Linux64. The first replay runner incorrectly used Edit Mode despite roster's Play Mode requirement; the next used a one-slot roster for a second-slot test. Both fixture setup mistakes were corrected, without relaxing runtime ownership checks. Their failing logs are private, not product regressions or passing evidence.

Preservation and next work

Private capture /tmp/tinychaos-batch51-preserve-32cb812aee/ retains 7,755 pre-existing project files and 8,178 profile hashes with recoverable bytes. 7,753 project files outside the two intended input edits match exactly, and eight added source/reference/metadata paths are the reviewed additions. Of 97 prior rebuild paths, 95 remain byte-identical; only the command frame/session intentionally change. The selected immutable baseline remains 600/608 with the same eight earlier exceptions; no repinning.

Attributed Linux toolchain 2.0.11 package additions and the generated Editor layout were archived; their exact pre-run bytes were restored. Graphical Editor initialization changed two existing session prefs and added 36 default UI/preferences keys; normal game prefs changed only four Unity session/connection keys. Generated copies were archived and original preference bytes restored after all owned Editors exited. Normal game file membership and its one prefs file are unchanged. Other external engine logs/licensing/layout/search/event bookkeeping has 7 changed, 9 added and 6 removed files; the full profile tree is not claimed unchanged. The unresolved audio deletions and untracked Addressables Linux.meta remain untouched. No owned Editor remains running.

Inventory covers 266 scripts: 261 prior rows stay byte-preserved, two update and three are added. Three KB gates append to 155 prior rows. All 27 open workstream follow-ups remain open. The original source contract CSVs, input consumers and authored baselines are not rewritten. Documentation validation resolves all 881 local links and keeps all 53 issues routed once. Logs, full traces, screenshots and profiles remain outside Git.

Next resolve the sampler's continuing session timeline/first-activation behavior, extract one authoritative motor shared by the production facade and prepared actor, compare original outputs, then activate that capability. Analog processing, facing/collision integration, full dash/vitals/AbilityHolder/combat, physical devices, Windows and complete gameplay remain open. New menus/UI, Tutorial and dedicated GAME-01 work remain deferred.