Split The code is public; the app answers only to the crew.
Aim goes through the OS pointer acceleration, and a refused pointer lock leaves a live match you cannot aim in #225
Sign in to join this conversation.
Split The code is public; the app answers only to the crew.
Intent: the mouse aims with the raw counts the sensor sends, and when the browser refuses the pointer lock the match stays paused instead of running with no way to aim.
What is true today (at
3118dc1)lock(src/client/main.ts:411) isvoid scene.requestPointerLock()with no options. On browsers that support it,{ unadjustedMovement: true }switches off the operating system's pointer acceleration. Without it, the same 5 cm swipe turns you a different number of degrees depending on how fast you made it. Every sensitivity setting the game offers (#198's scoped curve, the menu's sensitivity) sits on top of a curve the player never chose.voidswallows the rejection, and nopointerlockerrorlistener exists (grep -rn pointerlockerror srcfinds nothing). Chrome refuses a re-lock for about a second after the player presses Esc. So pressing Esc and then clicking Resume straight away (main.ts:744–749) takes down the pause overlay,lock()fails, andpointerlockchangenever fires. The match is now live behind a free cursor: mouse movement does nothing (input.ts:233gates oncontrols.locked), and nothing puts the pause back up.Done looks like
src/client/lock.ts, owns the request. It takes the element (anything withrequestPointerLock) and returns a result that is plain data:"raw" | "plain" | "refused".- It tries
{ unadjustedMovement: true }first. If that rejects withNotSupportedError, it tries once with no options. - It handles arequestPointerLockthat returnsundefined(older Firefox/Safari) as"plain", pending thepointerlockchange. - Any other rejection is"refused".main.ts'slock()uses it. On"refused"it keeps the match paused, with the overlay back up and a one-line reason (e.g. "Click Resume again to take the mouse"), in the same voice as the lost-view note.lock.test.tsdrives a fake element through all four paths (raw accepted, raw unsupported → plain accepted,undefinedreturn, refused). Each test would fail without the module.coarse) still never asks, as today.bun run checkis green.Files:
src/client/lock.ts(new),src/client/lock.test.ts(new),src/client/main.ts,README.md.Risks
main.tsis also where #114 (the rebind panel's wiring) lands. Keep the change tolock()and the Resume handler.Suggested brief: scout (client wiring and its harness).