Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
Mini Arcade
Mini Arcade

Start Here

  • README
  • Quickstart
  • Architecture
  • Capabilities
  • Configuration Internals
  • Backends Internals
  • Scene Internals
  • Grid Gameplay Internals
  • Falling Blocks Internals
  • Brick Breaker Internals
  • Maze Gameplay Internals
  • Bomberman Gameplay Internals
  • Menu Scenes Internals
  • Scene Transitions Internals
  • Overlay Policies Internals
  • Window and Viewport Internals
  • Entities Internals
  • Shapes and Layering Internals
  • Sprites and Animations Internals
  • Input Coordinate Mapping Internals
  • Tutorials
    • Create a Game
    • config/engine_config_basics
    • config/backend_swap
    • scene/minimal_scene
    • scene/change_scene
    • scene/menu_scene_base
    • scene/pause_overlay_policy
    • scene/debug_overlay_builtin
    • window/virtual_resolution_basics
    • window/fit_vs_fill
    • window/resize_reflow
    • window/screen_to_virtual_input
    • entity/base_entity_from_dict
    • entity/shape_primitives_gallery
    • entity/z_index_and_layer_intuition
    • entity/sprite_texture_basics
    • entity/animation_frames_basics
    • systems/input_frame_visualizer
    • systems/action_map_variants
    • systems/phases_and_order
    • systems/pause_intent_builtin
    • systems/animation_tick_builtin
    • systems/cull_viewport_builtin
    • commands/custom_scene_commands
    • commands/scene_stack_commands
    • commands/cheat_sequences
    • commands/effect_and_debug_hotkeys
    • Roadmap
  • Games
    • Asteroids
    • Deja Bounce
    • Space Invaders
  • Contributing
    • Dev setup
    • Repo layout
    • Release process

API Reference

  • API Reference
    • mini_arcade
      • mini_arcade.app
      • mini_arcade.backends
        • mini_arcade.backends.native
        • mini_arcade.backends.pygame
      • mini_arcade.cli
        • mini_arcade.cli.argument_type
        • mini_arcade.cli.base_command
        • mini_arcade.cli.base_command_processor
        • mini_arcade.cli.cli
        • mini_arcade.cli.command_protocol
        • mini_arcade.cli.exceptions
        • mini_arcade.cli.registry
      • mini_arcade.constants
      • mini_arcade.core
      • mini_arcade.main
      • mini_arcade.modules
        • mini_arcade.modules.backend_loader
        • mini_arcade.modules.game_runner
          • mini_arcade.modules.game_runner.commands
          • mini_arcade.modules.game_runner.processors
        • mini_arcade.modules.game_scaffold
          • mini_arcade.modules.game_scaffold.commands
          • mini_arcade.modules.game_scaffold.processors
        • mini_arcade.modules.settings
        • mini_arcade.modules.system_lab
          • mini_arcade.modules.system_lab.commands
          • mini_arcade.modules.system_lab.processors
          • mini_arcade.modules.system_lab.registry
          • mini_arcade.modules.system_lab.visual_runner
        • mini_arcade.modules.system_lab_scaffold
          • mini_arcade.modules.system_lab_scaffold.commands
          • mini_arcade.modules.system_lab_scaffold.processors
      • mini_arcade.utils
        • mini_arcade.utils.get_package_version
        • mini_arcade.utils.implementation_registry
        • mini_arcade.utils.logging
        • mini_arcade.utils.module_loader
    • mini_arcade_core
      • mini_arcade_core.backend
        • mini_arcade_core.backend.backend
        • mini_arcade_core.backend.config
        • mini_arcade_core.backend.events
        • mini_arcade_core.backend.keys
        • mini_arcade_core.backend.sdl_map
        • mini_arcade_core.backend.types
        • mini_arcade_core.backend.utils
        • mini_arcade_core.backend.viewport
      • mini_arcade_core.bus
      • mini_arcade_core.engine
        • mini_arcade_core.engine.animation
        • mini_arcade_core.engine.cheats
        • mini_arcade_core.engine.commands
        • mini_arcade_core.engine.components
        • mini_arcade_core.engine.engine_config
        • mini_arcade_core.engine.entities
        • mini_arcade_core.engine.game
        • mini_arcade_core.engine.game_config
        • mini_arcade_core.engine.gameplay_settings
        • mini_arcade_core.engine.loop
          • mini_arcade_core.engine.loop.config
          • mini_arcade_core.engine.loop.hooks
          • mini_arcade_core.engine.loop.runner
          • mini_arcade_core.engine.loop.state
        • mini_arcade_core.engine.managers
        • mini_arcade_core.engine.render
          • mini_arcade_core.engine.render.camera
          • mini_arcade_core.engine.render.context
          • mini_arcade_core.engine.render.effects
            • mini_arcade_core.engine.render.effects.base
            • mini_arcade_core.engine.render.effects.crt
            • mini_arcade_core.engine.render.effects.registry
            • mini_arcade_core.engine.render.effects.vignette
          • mini_arcade_core.engine.render.frame_packet
          • mini_arcade_core.engine.render.packet
          • mini_arcade_core.engine.render.passes
            • mini_arcade_core.engine.render.passes.base
            • mini_arcade_core.engine.render.passes.begin_frame
            • mini_arcade_core.engine.render.passes.end_frame
            • mini_arcade_core.engine.render.passes.lighting
            • mini_arcade_core.engine.render.passes.postfx
            • mini_arcade_core.engine.render.passes.ui
            • mini_arcade_core.engine.render.passes.world
          • mini_arcade_core.engine.render.pipeline
          • mini_arcade_core.engine.render.render_service
          • mini_arcade_core.engine.render.style
          • mini_arcade_core.engine.render.viewport
        • mini_arcade_core.engine.scenes
          • mini_arcade_core.engine.scenes.models
          • mini_arcade_core.engine.scenes.scene_manager
      • mini_arcade_core.runtime
        • mini_arcade_core.runtime.audio
          • mini_arcade_core.runtime.audio.audio_adapter
          • mini_arcade_core.runtime.audio.audio_port
        • mini_arcade_core.runtime.capture
          • mini_arcade_core.runtime.capture.base_worker
          • mini_arcade_core.runtime.capture.capture_port
          • mini_arcade_core.runtime.capture.capture_service
          • mini_arcade_core.runtime.capture.capture_service_protocol
          • mini_arcade_core.runtime.capture.capture_settings
          • mini_arcade_core.runtime.capture.capture_worker
          • mini_arcade_core.runtime.capture.encode_worker
          • mini_arcade_core.runtime.capture.event_handlers
          • mini_arcade_core.runtime.capture.events
          • mini_arcade_core.runtime.capture.replay
          • mini_arcade_core.runtime.capture.replay_format
          • mini_arcade_core.runtime.capture.screenshot_capturer
          • mini_arcade_core.runtime.capture.video
          • mini_arcade_core.runtime.capture.video_encoder
          • mini_arcade_core.runtime.capture.video_manifest
        • mini_arcade_core.runtime.context
        • mini_arcade_core.runtime.file
          • mini_arcade_core.runtime.file.file_adapter
          • mini_arcade_core.runtime.file.file_port
        • mini_arcade_core.runtime.input
          • mini_arcade_core.runtime.input.input_adapter
          • mini_arcade_core.runtime.input.input_port
        • mini_arcade_core.runtime.input_frame
        • mini_arcade_core.runtime.render
          • mini_arcade_core.runtime.render.render_port
        • mini_arcade_core.runtime.scene
          • mini_arcade_core.runtime.scene.scene_query_adapter
          • mini_arcade_core.runtime.scene.scene_query_port
        • mini_arcade_core.runtime.services
        • mini_arcade_core.runtime.window
          • mini_arcade_core.runtime.window.window_adapter
          • mini_arcade_core.runtime.window.window_port
      • mini_arcade_core.scenes
        • mini_arcade_core.scenes.autoreg
        • mini_arcade_core.scenes.bootstrap
        • mini_arcade_core.scenes.debug_overlay
        • mini_arcade_core.scenes.entity_blueprints
        • mini_arcade_core.scenes.game_scene
        • mini_arcade_core.scenes.registry
        • mini_arcade_core.scenes.sim_scene
        • mini_arcade_core.scenes.systems
          • mini_arcade_core.scenes.systems.base_system
          • mini_arcade_core.scenes.systems.builtins
            • mini_arcade_core.scenes.systems.builtins.actions
            • mini_arcade_core.scenes.systems.builtins.animation
            • mini_arcade_core.scenes.systems.builtins.bomberman
            • mini_arcade_core.scenes.systems.builtins.brick_breaker
            • mini_arcade_core.scenes.systems.builtins.capture_hotkeys
            • mini_arcade_core.scenes.systems.builtins.falling_blocks
            • mini_arcade_core.scenes.systems.builtins.grid
            • mini_arcade_core.scenes.systems.builtins.intent_commands
            • mini_arcade_core.scenes.systems.builtins.maze
            • mini_arcade_core.scenes.systems.builtins.movement
            • mini_arcade_core.scenes.systems.builtins.particles
            • mini_arcade_core.scenes.systems.builtins.pause
            • mini_arcade_core.scenes.systems.builtins.powerups
            • mini_arcade_core.scenes.systems.builtins.projectiles
            • mini_arcade_core.scenes.systems.builtins.score_chain
            • mini_arcade_core.scenes.systems.builtins.spawn
            • mini_arcade_core.scenes.systems.builtins.timers
          • mini_arcade_core.scenes.systems.phases
          • mini_arcade_core.scenes.systems.system_bundle
          • mini_arcade_core.scenes.systems.system_pipeline
      • mini_arcade_core.spaces
        • mini_arcade_core.spaces.behaviors
        • mini_arcade_core.spaces.collision
          • mini_arcade_core.spaces.collision.intersections
          • mini_arcade_core.spaces.collision.rect_collider
          • mini_arcade_core.spaces.collision.specs
        • mini_arcade_core.spaces.d2
          • mini_arcade_core.spaces.d2.boundaries2d
          • mini_arcade_core.spaces.d2.collision2d
          • mini_arcade_core.spaces.d2.kinematics2d
          • mini_arcade_core.spaces.d2.physics2d
        • mini_arcade_core.spaces.geometry
          • mini_arcade_core.spaces.geometry.bounds
          • mini_arcade_core.spaces.geometry.shapes
          • mini_arcade_core.spaces.geometry.size
          • mini_arcade_core.spaces.geometry.transform
        • mini_arcade_core.spaces.math
          • mini_arcade_core.spaces.math.vec2
        • mini_arcade_core.spaces.physics
          • mini_arcade_core.spaces.physics.kinematics2d
      • mini_arcade_core.ui
        • mini_arcade_core.ui.menu
      • mini_arcade_core.utils
        • mini_arcade_core.utils.assets
        • mini_arcade_core.utils.deprecated_decorator
        • mini_arcade_core.utils.logging
        • mini_arcade_core.utils.profiler
    • mini_arcade_pygame_backend
      • mini_arcade_pygame_backend.config
      • mini_arcade_pygame_backend.ports
        • mini_arcade_pygame_backend.ports.audio
        • mini_arcade_pygame_backend.ports.capture
        • mini_arcade_pygame_backend.ports.input
        • mini_arcade_pygame_backend.ports.render
        • mini_arcade_pygame_backend.ports.text
        • mini_arcade_pygame_backend.ports.window
      • mini_arcade_pygame_backend.pygame_backend
    • mini_arcade_native_backend
      • mini_arcade_native_backend.config
      • mini_arcade_native_backend.dlls
      • mini_arcade_native_backend.mapping
        • mini_arcade_native_backend.mapping.events
      • mini_arcade_native_backend.native_backend
      • mini_arcade_native_backend.ports
        • mini_arcade_native_backend.ports.audio
        • mini_arcade_native_backend.ports.capture
        • mini_arcade_native_backend.ports.input
        • mini_arcade_native_backend.ports.render
        • mini_arcade_native_backend.ports.text
        • mini_arcade_native_backend.ports.window
Back to top
View this page

Menu Scenes Internals¶

Purpose¶

Explain how BaseMenuScene works internally, what extension points it exposes, and how to apply it for main menus and pause overlays.

Core implementation¶

Main file:

  • packages/mini-arcade-core/src/mini_arcade_core/ui/menu.py

Key types:

  • MenuItem: menu entry id, static label, command_factory, optional label_fn

  • MenuStyle: style/layout options (background, panel, button style, hint, text colors)

  • Menu: render + selection state + layout calculations

  • BaseMenuScene: scene base class that wires menu systems

BaseMenuScene contract¶

Implement in your scene subclass:

  • menu_title: title text shown at top (None hides title)

  • menu_style(): returns MenuStyle for look and layout

  • menu_items(): returns menu entries and command factories

Optional:

  • quit_command(): command used when ESC is pressed in menu (default is QuitCommand)

Per-frame system pipeline¶

BaseMenuScene.on_enter() registers these systems in order:

  1. MenuInputSystem

  2. MenuNavigationSystem

  3. MenuActionSystem

  4. MenuRenderSystem

Runtime flow:

  1. input keys become MenuIntent

  2. selection index updates (with cooldown)

  3. selected action enqueues command

  4. menu is rendered as UI draw op

Command model in menus¶

MenuItem.command_factory returns a command instance each selection.

Typical commands:

  • ChangeSceneCommand(...) for scene transitions

  • RemoveSceneCommand(...) for dismissing pause overlays

  • QuitCommand() for full exit

  • custom commands mutating gameplay settings (difficulty, toggles, etc.)

Dynamic labels¶

label_fn(ctx) is evaluated each tick to resolve display label. This supports menu text driven by runtime state:

  • difficulty level

  • audio on/off state

  • control profile name

  • backend/debug options

Pattern:

  1. command mutates runtime state

  2. next frame, label_fn reads updated state

  3. menu label updates without scene restart

Main menu vs pause overlay¶

Main menu pattern:

  • usually opaque standalone scene

  • sets background_color, panel_color, and button styles

  • ESC often maps to QuitCommand

Pause overlay pattern:

  • pushed with overlay ScenePolicy (as_overlay=True)

  • menu style usually uses overlay_color dimming

  • quit_command() typically resumes gameplay, not exit

Policy details for pause overlays:

  • docs/source/concepts/overlay_policies.md

See real game implementations:

  • games/deja-bounce/src/deja_bounce/scenes/menu.py

  • games/deja-bounce/src/deja_bounce/scenes/pause.py

  • games/asteroids/src/asteroids/scenes/menu.py

  • games/asteroids/src/asteroids/scenes/pause.py

  • games/space-invaders/src/space_invaders/scenes/menu.py

  • games/space-invaders/src/space_invaders/scenes/pause.py

Common mistakes¶

  • forgetting scene discovery package: menu scene never registers

  • returning a command class that needs args without wrapping it in a factory

  • mutating menu labels manually instead of using label_fn

  • assuming pause overlay should use default quit_command (which exits game)

Related tutorial¶

  • docs/source/tutorials/scene/menu_scene_base.md

Next
Scene Transitions Internals
Previous
Bomberman Gameplay Internals
Copyright © 2026, Santiago Rincon
Made with Sphinx and @pradyunsg's Furo
On this page
  • Menu Scenes Internals
    • Purpose
    • Core implementation
    • BaseMenuScene contract
    • Per-frame system pipeline
    • Command model in menus
    • Dynamic labels
    • Main menu vs pause overlay
    • Common mistakes
    • Related tutorial