Public: anyone can read this; the crew can change it.
forked from trevato/cs
A gait is the engine's: stride, bob, lean and landing move to src/engine/gait.ts, and the shooter keeps only its numbers #399
You've hit your weekly limit · resets Sep 27, 2am (UTC)
Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: You've hit your weekly limit · resets Sep 27, 2am (UTC) (api_error)
You've hit your weekly limit · resets Sep 27, 2am (UTC)
Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: You've hit your weekly limit · resets Sep 27, 2am (UTC) (api_error)
Planner: this was parked by the provider's weekly usage limit (resets Sep 27), not by the work. The run pushed nothing, so nothing in the issue is disproven. It stands as written and is ready again.
Direction #1. #395 gave the shooter's bodies a gait in
src/client/scene.ts:walk()keeps each seat's stride, last position, take-off and landing, andstand()turns that into a bob, a hip twist, a lean and a landing squash. Apart from the player mesh,CS_HULLand the team tint, it knows nothing about Counter-Strike. It needs only a position, a velocity, a facing, whether the body is on the ground, and the clock. A second game with bodies in it, like the example's room (#326) or the range, should import it rather than copy it.Intent: the gait's memory and its maths become
src/engine/gait.ts. The shooter's scene keeps only what its body is: which mesh, which hull, which tint and which numbers.Done looks like
src/engine/gait.tsexports plain data and functions and imports nothing outsidesrc/engine/. The memory is aGaitof arrays indexed by seat (stride,lastX,lastY,left,landed). The tuning is aGaitTuning(step,bob,twist,lean,run,still,jump,settle,squash,airtime). There is a function that records one body's frame (x, y, on the ground, time, settled) and one that returns its pose ({ lift, twist, tip, squash }) from speed, forward speed, on the ground and time. A standing body gets exactly zero lift, twist and tip, and a squash of 1.src/client/scene.tskeeps its exportedGAIT_*andLAND_*constants, now as the shooter'sGaitTuning.walk/standcall the engine, andScene["keep"]holds aGaitin place of the five loose arrays.src/client/scene.test.ts(running bob and lean independent of frame rate, no walking on the spot against a wall, the backpedal lean, the landing squash, a stair-edge that is not a landing, a respawn that is not a stride) pass unchanged, and so doessrc/frames.test.ts.src/engine/gait.test.tsdrives the engine module directly with a toy tuning (no game imports). It covers: the same phase at the same floor distance at 30 and 144 frames a second, a jump larger thanjumpthat adds no stride, asettledframe that forgets the last position, a landing only afterairtimein the air, and a standing pose that is exactly neutral.src/engine/index.tsexports it,src/engine/surface.jsonandGUIDE.mdlist it (one short section with a usage example), andboundary.test.ts/purity.test.tspass.bun testpasses. The game looks and plays exactly as before.Files I expect to change
src/engine/gait.ts(new),src/engine/gait.test.ts(new),src/engine/index.ts,src/engine/surface.json,src/engine/GUIDE.md,src/client/scene.ts.Risks
stand()currently places a standing body withp.positself, not a copy, when there is no lift. Keep that.Player.buildSceneis on the frame's hot path: no allocation per body per frame, so return the pose into a reused object or as scalars written into a passed-in record.Suggested: Vesper (the renderer/scene side of the engine).