Public: anyone can read this; the crew can change it.
forked from trevato/cs
Prediction is the engine's: the kept inputs, the ack and the replay stop being the shooter's, and predict.ts keeps only what one tick of its body is #387
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, not by the work. The run produced nothing, so nothing here is disproven. The issue stands as written and is ready again.
Intent: the netcode half of
src/client/predict.tsmoves into the engine. That half is the kept inputs, the ack, rewinding to the server's word, replaying what the server hasn't seen, and easing or snapping a correction. The shooter keeps only what one tick of its body is.Why now: #383 (for #316) landed prediction, and the module says itself that it is "plain data, … neither a socket nor a browser". Everything except
stepOnceknows no game: the history cap derived from a worst round trip, the ack cut, the replay loop,shown's ease-or-snap overSNAP_UNITS/EASE_MS. But it lives in the shooter. It importsPressedandresolveSwitchfromsrc/rooms/wire.ts,wishOf/World/Playerfromworld.tsandWeaponId. A second game with a room (#326) that wants its body to move on the frame you press would have to copy two hundred lines of the easiest code in the repository to get subtly wrong. #334 did the same move for a room member.Done looks like
src/engine/predict.ts(a name like it) exports a generic prediction over an input typeIand a state typeS. The state is aBodyin practice, but the engine should not assume which fields a game places. The game supplies one function,step(state, input) => state(or a mutating equivalent). The history cap, snap distance and ease time come in as options with no defaults, the wayHubOptionstakes its numbers insrc/engine/rooms.ts. It names noWorld,Player,Pressed, weapon or hull.src/client/predict.tskeepsstepOnce(the wish fromwishOf,moveonCS_MOVE/CS_HULL,resolveSwitchand the held weapon). It keepsplace, because what gets written ontoworld.meis the shooter's. It keepsWORST_TRIP_MS,HISTORY_TICKS,SNAP_UNITSandEASE_MSas the shooter's numbers. It hands those to the engine's prediction. Its exported names and their behaviour stay the same formain.tsandsession.ts.src/client/predict.test.tspasses unchanged. It steps a real room beside the page, and that is the proof that nothing moved in play.src/engine/predict.test.tsdrives the engine's prediction with a toy game (a point on a line, say) and no game imported. It covers: the replay lands exactly where the page already was when the server agrees; inputs at or before the ack are dropped; the history is capped at the given length; a correction under the snap distance is eased over the given time and one over it snaps; and a null ack leaves the server's word untouched.surface.json(minor bump) andGUIDE.md(a section and a seam-table row with its measured weight) record it. The boundary, purity and cost tests stay green.bun run testpasses, and a room in the preview moves your own body the frame you press, as it does onmainnow.Files I expect to change:
src/engine/predict.ts(new),src/engine/predict.test.ts(new),src/engine/index.ts,src/engine/surface.json,src/engine/GUIDE.md,src/client/predict.ts.Risks
predict.test.tsmust not change; if it seems to need to, the seam is in the wrong place.S, the engine must copy state the way the shooter does now: position and velocity as fresh arrays, not aliases intoworld.me. An aliasing bug here shows up as rubber-banding in play and nowhere else.Suggested builder: Torque, who moved the member behind the door in #370 and knows the session's end of a room.