Answer

Fix pattern: 1. Keep menu screens and in-game overlays in separate input modes. Startup/customization menus can force Mouse.Visibility = Visible and keep pointer events enabled because they are actual UI scenes. 2. For an in-game Tab overlay, make the shared ScreenPanel host configurable, for example CapturePointerEvents = true by default but PointerEvents.None when the overlay is closed. 3. When opening the overlay, set the host to capture pointer events and set Mouse.Visibility = Visible. 4. When closing the overlay, set the host/root to PointerEvents.None and set Mouse.Visibility = Hidden so s&box locks mouse input back to gameplay. 5. Add a regression check that asserts the in-game overlay only passes capturePointerEvents: overlay.IsOpen, while startup/customization panels keep their own visible mouse behavior. The key is that a hidden full-screen Panel with PointerEvents.All still counts as clickable UI for MouseVisibility.Auto. Keyboard movement continuing to work is a clue that the PlayerController is alive and the mouse is being intercepted by UI state instead.

3f2514f4-4a79-43c0-9a6a-ac8b237623f3

Fix pattern:

  1. Keep menu screens and in-game overlays in separate input modes. Startup/customization menus can force Mouse.Visibility = Visible and keep pointer events enabled because they are actual UI scenes.

  2. For an in-game Tab overlay, make the shared ScreenPanel host configurable, for example CapturePointerEvents = true by default but PointerEvents.None when the overlay is closed.

  3. When opening the overlay, set the host to capture pointer events and set Mouse.Visibility = Visible.

  4. When closing the overlay, set the host/root to PointerEvents.None and set Mouse.Visibility = Hidden so s&box locks mouse input back to gameplay.

  5. Add a regression check that asserts the in-game overlay only passes capturePointerEvents: overlay.IsOpen, while startup/customization panels keep their own visible mouse behavior.

The key is that a hidden full-screen Panel with PointerEvents.All still counts as clickable UI for MouseVisibility.Auto. Keyboard movement continuing to work is a clue that the PlayerController is alive and the mouse is being intercepted by UI state instead.