scene/debug_overlay_builtin¶
Goal¶
Understand exactly how the built-in debug overlay works, why F1 toggles it,
and what scene stack/input policy it uses.
Why this tutorial exists¶
This is the first scene-stack tutorial that explains a built-in overlay scene managed by engine commands, not by your game code.
It demonstrates:
event hook -> command queue -> scene stack flow
policy behavior (
overlay,blocks_update,blocks_input,receives_input)required scene discovery so
debug_overlaycan be instantiated
Source map¶
Example settings:
examples/settings/scene/debug_overlay_builtin.ymlExample builder:
examples/catalog/scene/debug_overlay_builtin/main.pyExample scene:
examples/catalog/scene/debug_overlay_builtin/scenes/scene.pyBuilt-in overlay scene:
packages/mini-arcade-core/src/mini_arcade_core/scenes/debug_overlay.pyF1 hook:
packages/mini-arcade-core/src/mini_arcade_core/engine/loop/hooks.pyToggle command:
packages/mini-arcade-core/src/mini_arcade_core/engine/commands.py
Internal flow (actual runtime path)¶
When you press F1, this is what happens:
DefaultGameHooks.on_events(...)receivesKEYDOWN(F1)and enqueuesToggleDebugOverlayCommand.EngineRunnerdrains command queue in the same frame.ToggleDebugOverlayCommand.execute(...):removes
debug_overlayif already on stackotherwise pushes scene id
debug_overlayas overlay with policy:blocks_update=Falseblocks_input=Falseis_opaque=Falsereceives_input=False
DebugOverlayScene.tick(...)renders telemetry lines (fps, dt, viewport, render stats, stack summary).
No game-specific scene code is needed for this toggle behavior.
Critical config requirement¶
Your scene discovery must include:
your example/game scene package
mini_arcade_core.scenes
This tutorial profile sets both:
scene:
scene_registry:
discover_packages:
- examples.catalog.scene.debug_overlay_builtin
- mini_arcade_core.scenes
If mini_arcade_core.scenes is missing, pressing F1 cannot create
debug_overlay and overlay toggle appears to do nothing.
Code excerpt¶
From ToggleDebugOverlayCommand:
if scenes.has_scene("debug_overlay"):
scenes.remove_scene("debug_overlay")
else:
scenes.push(
"debug_overlay",
as_overlay=True,
policy=ScenePolicy(
blocks_update=False,
blocks_input=False,
is_opaque=False,
receives_input=False,
),
)
From this tutorial scene (debug_overlay_builtin):
stack = list(services.scenes.visible_entries())
input_owner = services.scenes.input_entry()
overlay_active = any(e.scene_id == "debug_overlay" for e in stack)
It prints stack + input owner so you can verify policy behavior while toggling.
Run¶
Default:
mini-arcade run --example scene/debug_overlay_builtin
Force pygame:
mini-arcade run --example scene/debug_overlay_builtin --pass-through --backend pygame
Force native:
mini-arcade run --example scene/debug_overlay_builtin --pass-through --backend native
What to verify¶
F1shows and hides the built-in telemetry panel.overlay activeflipsFalse/Truein the base scene.input owner sceneremainsdebug_overlay_builtineven when overlay is visible.animation/frame counter continue while overlay is visible (
blocks_update=Falseon overlay policy).ESCexits cleanly.
Built-in overlay vs game overlays¶
Use built-in overlay for engine/runtime telemetry during development.
Use game overlays (pause menus, modal UI) when gameplay flow should be blocked. Reference pause overlays in shipped games:
games/deja-bounce/src/deja_bounce/scenes/commands.pygames/asteroids/src/asteroids/scenes/commands.pygames/space-invaders/src/space_invaders/scenes/commands.py
Those overlays usually set blocks_update=True and blocks_input=True.
Next step¶
Build a command-driven menu scene: menu_scene_base.md