A Controller File Lost Half Its Length
An action-based InputSystem with stacked contexts and per-frame press state, and two controllers cut by more than a third after adopting it.
Actions, Not Keys
movement move_forward move_back move_left move_right move_up move_down
rotate_left rotate_right
camera camera_pan camera_zoom_in camera_zoom_out
common interact cancel confirm
menu menu_up menu_down menu_left menu_rightEvery binding goes through InputSystem, which supports context stacking (gameplay, menu, dialog), frame-based state (wasPressed, wasReleased, isActive) and configurable bindings. Touch gestures and gamepads are noted as planned; keyboard and mouse shipped.
The Refactor Is the Feature
FPSController.ts 340 -> 160 lines (-53%)
SideScrollController.ts 257 -> 178 lines (-31%)Neither controller knows what a key is any more. IsometricController kept a direct BabylonJS pointer observable, because ground raycasting needs the pointer and pretending otherwise would have been slower.
The Frame Ordering Rule
InputSystem updates before render, controllers query during the render observer, and per-frame state is cleared after render. Write that down as three lines, because it is exactly the rule that gets violated later — and did, in v0.9.11, when framerate-dependent physics turned out to be running commands at dt / queue.length.
Known Issues: none stated.