Two distinct features today, both driven by the same need: the game is getting complex enough that systems are stepping on each other.
The input problem
When a modal window opens (tutorial prompt, pause menu, settings), the player shouldn’t be able to walk around, open other menus, or interact with the game world. Sounds obvious, but Roblox doesn’t give you this for free. ContextActionService can sink specific inputs, UserInputService fires regardless of UI state, and the character controller keeps running unless you explicitly freeze it.
Most Roblox games handle this by scattering enabled flags everywhere — canMove, menuOpen, isTutorialActive. It works until two systems both set canMove = false and the second one sets it back to true when it closes, not knowing the first one still needs movement disabled.
The focus stack
We built a centralized input management system modeled on how operating systems handle window focus. When a system needs exclusive input, it claims focus:
local claim = InputCapture.claim({}, {
sinkMovement = true, -- block WASD/thumbstick
sinkCamera = true, -- block camera rotation
disablePlayerModule = true, -- freeze character controller
})
-- Later, when the modal closes:
claim:release()
Claims stack. If the pause menu claims focus and then a confirmation dialog claims on top of it, releasing the dialog falls back to the pause menu’s claim — movement stays disabled. Only when all claims are released does normal input resume.
This eliminates the “who set this flag?” problem. Each system manages its own claim, and the InputCapture module resolves conflicts automatically.
Unified styling for GUI and 3D
The CSS-like styling system from Day 6 only worked on GUI elements (Frames, TextLabels, etc.). But we also have 3D objects that need consistent styling — BillboardGuis floating above NPCs, SurfaceGuis on machines, colored Parts that should match the game’s palette.
We extended the styling system to cover both. A single style definition can set BackgroundColor3 on a Frame or Color on a Part. The system inspects the target instance’s class and maps property names to the appropriate Roblox properties. Same API, same style tables, whether you’re styling pixels on screen or objects in the world.
This matters for theming. When we eventually add color palettes (spoiler: Day 22), changing a theme applies to both UI and 3D objects through the same system.