Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
SIMVX
HomeExamplesEditorDocs
SimVX documentation
SimVX documentation

Getting Started

  • Installation
  • Quickstart
  • Your First 2D Game
  • Your First 3D Game
  • From Monolithic to Composed
  • Patterns
  • Examples Gallery
    • Animated Sprite
    • Area2D
    • Bloom 2D
    • Bunnymark
    • Camera2D
    • Collision Shapes
    • Blend Modes
    • GPU Particle Fireworks
    • GPU Particles 2D
    • 2D Joints
    • Game feel
    • Layer post
    • 2D Lighting
    • Line joints and caps
    • Navigation
    • NinePatchRect
    • 2D Path Follow
    • Post shader
    • Procedural dungeon
    • Screen Effects 2D
    • Skeleton2D
    • Sprite
    • Texture resource
    • TileMap
    • Timer
    • 2D Trail
    • Triangle
    • Tween
    • Animated Model
    • Animation Blend
    • Chase Camera
    • Physics Raycast Sandbox
    • Compressed texture
    • CSG
    • Custom post-process
    • Custom Shader
    • Custom Shader Textures
    • Cutout shadows
    • Decals
    • Dynamic procedural sky
    • Extrude Path
    • First-Person Camera
    • Fog
    • GPU Particles 3D
    • IBL
    • 3D Joints
    • 3D Lighting
    • LUT Grading
    • Transform Hierarchy
    • Model Viewer
    • Motion Blur
    • MultiMesh
    • 3D Navigation
    • Noise
    • Normal mapping
    • Occlusion culling
    • FFT ocean
    • Particles
    • 3D Path Follow
    • Mouse Picking
    • Planar reflection
    • Planar water
    • Point and spot shadows
    • Post-processing
    • Irradiance probe volume
    • Rain and wetness
    • Raycast
    • ReflectionProbe3D
    • Screen-space refraction
    • Render Layers
    • Render scale
    • RenderView
    • Rotating Cube
    • Shadow caster budget
    • Shadow Quality
    • Skeletal Animation
    • Split Screen
    • SSAO
    • Screen-space global illumination
    • Screen-space reflections
    • SubViewport
    • Per-view occlusion
    • TAA
    • TAAU
    • Rendering text
    • Procedural textures
    • Volumetric Fog
    • Water surface
    • World 2D in HDR
    • Agent Playtest
    • Real LLM loop against your OpenWebUI / vLLM / llama.cpp endpoint:
    • Offline (no endpoint): runs a scripted walk-through of the session verbs.
    • LLM NPC Flavour
    • Node-Gen
    • AI state machine
    • Steering behaviours
    • Audio Playback
    • Audio Buses
    • Music Streaming
    • Spatial Audio
    • Audio Spectrum
    • Lifecycle
    • Properties
    • SaveManager
    • Scene files
    • Signals
    • Debug Draw
    • Debug Overlay
    • Python Console
    • Terminal
    • Named input actions
    • Gamepad tester
    • Input Remapping
    • Body and World Knobs
    • Character Platformer
    • Character Presence
    • Character Push
    • Scaled Colliders
    • 2D Physics Playground
    • 3D Physics Playground
    • Sleeping Bodies
    • Dialogue Box
    • Touch Gestures
    • Health bars
    • HUD Anchors
    • Internationalisation
    • Grid Inventory
    • Menu Bar
    • Minimap
    • Pause Menu
    • Settings Screen
    • Splash Screen
    • Text Input
    • AppTheme presets
    • TreeView
    • Undo/Redo demo
    • Widget Showcase
    • Bouncing Balls
    • Bouncing Balls
    • First Scene
    • First Scene
    • Gem Collector
    • Gem Collector
    • Input and Movement
    • Input and Movement
    • Monolith to Composed
    • Monolith to Composed
    • Nodes and Signals
    • Nodes and Signals
    • Pong
    • Pong
    • Testing Your Game
    • Testing Your Game
      • test_game.py
    • Balatro Feel
    • Balatro Feel (SimVX port)
      • harness.py
      • nodes/__init__.py
      • nodes/card.py
      • nodes/card_textures.py
      • nodes/hand_holder.py
    • Casual Crusade
    • Casual Crusade (SimVX port)
      • harness.py
      • nodes/__init__.py
      • nodes/card.py
      • nodes/card_data.py
      • nodes/constants.py
      • nodes/dude.py
      • nodes/game.py
      • nodes/tile.py
    • Claustrowordia
    • Claustrowordia (SimVX port)
      • harness.py
      • nodes/__init__.py
      • nodes/audio.py
      • nodes/dictionary.py
      • nodes/game.py
      • nodes/grid.py
      • nodes/hand.py
      • nodes/textures.py
      • nodes/tile.py
    • Clear Code Zelda
    • Clear Code Zelda: SimVX port
      • capture.py
      • harness.py
      • nodes/__init__.py
      • nodes/anim_sprite.py
      • nodes/enemy.py
      • nodes/level.py
      • nodes/magic.py
      • nodes/menu.py
      • nodes/particles.py
      • nodes/player.py
      • nodes/touch.py
      • nodes/ui.py
      • nodes/upgrade.py
      • nodes/weapon.py
      • settings.py
      • support.py
    • Clumsy Bird
    • Clumsy Bird (SimVX port)
      • config.py
      • nodes/__init__.py
      • nodes/audio.py
      • nodes/bird.py
      • nodes/ground.py
      • nodes/hud.py
      • nodes/menu.py
      • nodes/pipe.py
      • nodes/play_scene.py
    • Dodge the Creeps
      • capture.py
      • nodes/__init__.py
      • nodes/audio.py
      • nodes/hud.py
      • nodes/mob.py
      • nodes/player.py
      • nodes/sprite_sheets.py
    • GDQuest Open RPG
    • GDQuest Open RPG: SimVX port
      • nodes/__init__.py
      • nodes/actions.py
      • nodes/audio_fx.py
      • nodes/battle.py
      • nodes/battler.py
      • nodes/dialogue.py
      • nodes/floating_label.py
      • nodes/gameboard.py
      • nodes/harness.py
      • nodes/hud.py
      • nodes/layout.py
      • nodes/npc.py
      • nodes/overworld.py
      • nodes/player.py
      • nodes/save_io.py
      • nodes/screen_transition.py
      • nodes/settings.py
      • nodes/sprites.py
      • nodes/stats.py
    • HeartBeast Action RPG
    • HeartBeast Action RPG: SimVX Port
      • nodes/__init__.py
      • nodes/effects.py
      • nodes/enemy.py
      • nodes/grass.py
      • nodes/hud.py
      • nodes/player.py
      • nodes/stats.py
      • nodes/ui.py
      • nodes/world.py
      • settings.py
    • HexGL
    • HexGL: SimVX Port
      • harness.py
      • nodes/__init__.py
      • nodes/ai_ship.py
      • nodes/camera.py
      • nodes/hud.py
      • nodes/menu.py
      • nodes/race.py
      • nodes/ship.py
      • nodes/track.py
    • Hextris
    • Hextris (SimVX port)
      • capture.py
      • nodes/__init__.py
      • nodes/game.py
      • nodes/hex_math.py
    • Mr. Rescue
    • Mr. Rescue: SimVX port
      • harness.py
      • nodes/__init__.py
      • nodes/audio.py
      • nodes/building.py
      • nodes/civilian.py
      • nodes/colours.py
      • nodes/enemy.py
      • nodes/fire.py
      • nodes/game.py
      • nodes/hud.py
      • nodes/menu.py
      • nodes/particles.py
      • nodes/player.py
      • nodes/textures.py
      • nodes/tile_grid.py
    • PirateMaker
    • PirateMaker: SimVX port
      • harness.py
      • nodes/__init__.py
      • nodes/editor.py
      • nodes/enemies.py
      • nodes/folder_sprite.py
      • nodes/hud.py
      • nodes/level.py
      • nodes/player.py
      • nodes/save_load.py
      • settings.py
      • sfx.py
      • support.py
    • Procedural Planets
    • Procedural Planets: SimVX Port
      • harness.py
      • nodes/__init__.py
      • nodes/colour.py
      • nodes/controls.py
      • nodes/planet.py
      • nodes/shape.py
      • nodes/terrain_face.py
      • nodes/title.py
    • Q1K3
    • Q1K3: SimVX port
      • harness.py
      • nodes/__init__.py
      • nodes/audio.py
      • nodes/door.py
      • nodes/enemy.py
      • nodes/hud.py
      • nodes/light.py
      • nodes/maps.py
      • nodes/mathutil.py
      • nodes/menu.py
      • nodes/meshes.py
      • nodes/particle.py
      • nodes/physics.py
      • nodes/pickup.py
      • nodes/player.py
      • nodes/projectile.py
      • nodes/prop.py
      • nodes/root.py
      • nodes/textures.py
      • nodes/touch.py
      • nodes/weapon.py
      • nodes/world.py
    • Asteroids (raylib classic)
      • __init__.py
      • nodes/__init__.py
      • nodes/asteroids_game.py
    • Snake (raylib classic)
    • Snake (raylib classic): SimVX port
      • __init__.py
      • nodes/__init__.py
      • nodes/snake_game.py
    • Tetris (raylib classic)
    • Tetris (raylib classic): SimVX port
      • __init__.py
      • nodes/__init__.py
      • nodes/tetris_game.py
    • SNKRX
    • SNKRX (SimVX port)
      • harness.py
      • nodes/__init__.py
      • nodes/arena.py
      • nodes/buy_screen.py
      • nodes/colours.py
      • nodes/enemies.py
      • nodes/hud.py
      • nodes/menu.py
      • nodes/particles.py
      • nodes/projectile.py
      • nodes/units.py
    • Klondike Solitaire
    • Klondike Solitaire: SimVX port
      • harness.py
      • nodes/card_node.py
      • nodes/card_textures.py
      • nodes/game_state.py
      • nodes/hud.py
      • nodes/menu.py
      • nodes/save_io.py
      • nodes/table.py
    • Squash the Creeps
      • nodes/__init__.py
      • nodes/arena.py
      • nodes/mob.py
      • nodes/player.py
    • Tanks of Freedom
    • Tanks of Freedom: SimVX port
      • harness.py
      • nodes/__init__.py
      • nodes/ai.py
      • nodes/building.py
      • nodes/combat.py
      • nodes/cursor.py
      • nodes/data.py
      • nodes/effects.py
      • nodes/hud.py
      • nodes/pathfinder.py
      • nodes/textures.py
      • nodes/tile_map.py
      • nodes/turn.py
      • nodes/unit.py
      • nodes/world.py
    • Tiny Yurts
    • Tiny Yurts (SimVX port)
      • harness.py
      • nodes/__init__.py
      • nodes/grid.py
      • nodes/iso.py
      • nodes/settler.py
      • nodes/world.py
    • Tower Defence
    • Tower Defence (SimVX port)
      • harness.py
      • nodes/__init__.py
      • nodes/audio.py
      • nodes/enemy.py
      • nodes/level_data.py
      • nodes/td_data.py
      • nodes/td_world.py
      • nodes/turret.py
    • Pixel Runner
    • Pixel Runner: SimVX Port
      • __init__.py
      • nodes/__init__.py
      • nodes/assets.py
      • nodes/audio.py
      • nodes/obstacle.py
      • nodes/player.py
      • nodes/runner.py
    • You’re the OS
    • You’re the OS: SimVX port
      • harness.py
      • nodes/__init__.py
      • nodes/stage.py
      • nodes/state.py
      • nodes/theme.py
    • Afterglow
    • Afterglow: original precision platformer (SimVX flagship demo)
      • afterglow/__init__.py
      • afterglow/assets/__init__.py
      • afterglow/assets/audio.py
      • afterglow/assets/sprite_gen.py
      • afterglow/assets/textures.py
      • afterglow/game.py
      • afterglow/progress.py
      • afterglow/sim/__init__.py
      • afterglow/sim/entities.py
      • afterglow/sim/room.py
      • afterglow/sim/rooms_data.py
      • afterglow/sim/tiles.py
      • afterglow/ui/__init__.py
      • afterglow/ui/controls.py
      • afterglow/ui/hud.py
      • afterglow/ui/menus.py
      • afterglow/view/__init__.py
      • afterglow/view/camera.py
      • afterglow/view/diorama.py
      • afterglow/view/effects.py
      • afterglow/view/environment.py
      • afterglow/view/lighting.py
      • afterglow/view/sprites.py
      • afterglow/view/title_backdrop.py
    • Asteroids 2D
    • Bloom
    • Bloom
      • ai.py
      • app.py
      • board.py
      • game.py
      • hex_grid.py
      • menu.py
      • render.py
      • web.py
    • Deep Sea Aquarium
      • __init__.py
      • boids.py
      • creatures.py
      • environment.py
      • meshgen.py
      • music.py
    • Dungeon Explorer
      • collision_layers.py
      • data/__init__.py
      • data/dialogs.py
      • events.py
      • nodes/__init__.py
      • nodes/_back_button.py
      • nodes/abilities.py
      • nodes/achievements.py
      • nodes/audio_manager.py
      • nodes/boss_enemy.py
      • nodes/boss_health_bar.py
      • nodes/camera_controller.py
      • nodes/combat.py
      • nodes/confirm_dialog.py
      • nodes/credits_screen.py
      • nodes/death_screen.py
      • nodes/dialog_ui.py
      • nodes/enchanter.py
      • nodes/enemy_base.py
      • nodes/enemy_types.py
      • nodes/game_manager.py
      • nodes/hotbar_assign_ui.py
      • nodes/inn.py
      • nodes/inventory_ui.py
      • nodes/item_tooltip.py
      • nodes/level_up_ui.py
      • nodes/loading_screen.py
      • nodes/loot_drop.py
      • nodes/loot_pickup.py
      • nodes/particles2d.py
      • nodes/pause_menu.py
      • nodes/player.py
      • nodes/player_hud.py
      • nodes/player_pause_bridge.py
      • nodes/projectile.py
      • nodes/quest_board.py
      • nodes/quest_log_ui.py
      • nodes/settings_ui.py
      • nodes/shop.py
      • nodes/skill_tree_ui.py
      • nodes/stats_tracker.py
      • nodes/title_screen.py
      • nodes/town.py
      • nodes/town_npc.py
      • nodes/transition_overlay.py
      • nodes/victory_screen.py
      • nodes/village.py
      • nodes/waypoint_ui.py
      • nodes/well.py
      • scripts/__init__.py
      • scripts/blacksmith.py
      • scripts/click_controller.py
      • scripts/dungeon_generator.py
      • scripts/dungeon_theme.py
      • scripts/enemy_spawner.py
      • scripts/fog_of_war.py
      • scripts/inventory.py
      • scripts/item.py
      • scripts/item_generator.py
      • scripts/mini_boss.py
      • scripts/player_skills.py
      • scripts/player_stats.py
      • scripts/quests.py
      • scripts/room_templates.py
      • scripts/save_state.py
      • scripts/tutorial.py
      • scripts/weapons.py
    • Pad Grid
    • Physics Sandbox
    • Planet Explorer
    • SHRIKE
    • SHRIKE
      • shrike/__init__.py
      • shrike/artkit.py
      • shrike/audio.py
      • shrike/balance.py
      • shrike/bounty.py
      • shrike/chart.py
      • shrike/combat.py
      • shrike/enemies/__init__.py
      • shrike/enemies/advanced.py
      • shrike/enemies/basic.py
      • shrike/enemies/steering.py
      • shrike/events.py
      • shrike/flow.py
      • shrike/hud.py
      • shrike/hunter.py
      • shrike/juice.py
      • shrike/meta.py
      • shrike/modules.py
      • shrike/onboarding.py
      • shrike/power.py
      • shrike/roost.py
      • shrike/runtime.py
      • shrike/save.py
      • shrike/sector.py
      • shrike/ship.py
      • shrike/signature.py
      • shrike/trading.py
      • shrike/vfx.py
      • shrike/waves.py
      • shrike/weapons.py
    • Space Invaders 2D
    • Space Invaders 3D
    • Squad Commander
    • Tic Tac Toe
      • demo.py
      • game.py
      • menu.py
      • web.py
    • Tidewater
  • Architecture
  • Building a Simple Game with the SimVX Editor
  • Shipping a Game

Core Engine

  • Core Engine
  • Node System
  • Input System
  • Windowing Backends
  • Animation
  • SimVX Audio System
  • AssetServer
  • UI System
  • Fonts and Languages
  • Math Types
  • Physics
  • Scenes
  • Particles
  • TileMap
  • 2D Lighting
  • Constructive Solid Geometry
  • Navigation
  • 3D Navigation
  • Skeleton
  • Physics Backends
  • WorldEnvironment
  • Testing
  • Performance regression suite
  • Package Resources
  • Save System
  • Event Bus

Graphics Backend

  • Graphics Backend
  • App Class
  • Cameras (3D)
  • Draw2D: immediate-mode 2D drawing
  • Materials
  • Compressed Textures (BC / ASTC / ETC2)
  • Blender to SimVX (glTF)
  • Custom Shaders
  • Visual Testing

Web

  • Web Export
  • Web export: resource channel

IDE

  • IDE

API Reference

  • API Reference
    • simvx.core
      • simvx.core.assets
        • simvx.core.assets.sources
          • simvx.core.assets.sources.mem
          • simvx.core.assets.sources.file
          • simvx.core.assets.sources.http
          • simvx.core.assets.sources.pkg
        • simvx.core.assets.loaders
          • simvx.core.assets.loaders.bytes_loader
          • simvx.core.assets.loaders.json_loader
          • simvx.core.assets.loaders.base
        • simvx.core.assets.server
        • simvx.core.assets.handle
        • simvx.core.assets.cache
        • simvx.core.assets.source
      • simvx.core.navigation
        • simvx.core.navigation.path_follower_2d
      • simvx.core.port_helpers
        • simvx.core.port_helpers.procedural_textures
      • simvx.core.ui
        • simvx.core.ui.ansi_parser
        • simvx.core.ui.splash
        • simvx.core.ui.rich_text
        • simvx.core.ui.advanced
        • simvx.core.ui.widgets
        • simvx.core.ui.markers
        • simvx.core.ui.text_paragraph
        • simvx.core.ui.navigation
        • simvx.core.ui.testing
        • simvx.core.ui.overlay
        • simvx.core.ui.containers
        • simvx.core.ui.clipboard
        • simvx.core.ui.file_browser
        • simvx.core.ui.terminal
        • simvx.core.ui.theme
        • simvx.core.ui.syntax_highlighter
        • simvx.core.ui.tooltip
        • simvx.core.ui.core
        • simvx.core.ui.dock
        • simvx.core.ui.find_replace
        • simvx.core.ui.tabs
        • simvx.core.ui.tree
        • simvx.core.ui.split
        • simvx.core.ui.graph_edit
        • simvx.core.ui.virtual_controls
        • simvx.core.ui.virtual_scroll
        • simvx.core.ui.completion_types
        • simvx.core.ui.file_dialog
        • simvx.core.ui.gamepad_overlay
        • simvx.core.ui.multiline
        • simvx.core.ui.focus
        • simvx.core.ui.scroll
        • simvx.core.ui.toolbar
        • simvx.core.ui.menu
        • simvx.core.ui.grid_slots
        • simvx.core.ui.code_editor_panel
        • simvx.core.ui.marks
        • simvx.core.ui.bottom_strip
        • simvx.core.ui.autocomplete
        • simvx.core.ui.folding
        • simvx.core.ui.colour_picker
        • simvx.core.ui.enums
        • simvx.core.ui.code_edit
        • simvx.core.ui.types
        • simvx.core.ui.ui_input
      • simvx.core.text
        • simvx.core.text.measure
        • simvx.core.text.msdf
        • simvx.core.text.font
        • simvx.core.text.bundled
      • simvx.core.scene_io
        • simvx.core.scene_io.symbols
        • simvx.core.scene_io.scene_file
        • simvx.core.scene_io.emitter
        • simvx.core.scene_io.layout
        • simvx.core.scene_io.source_tree
        • simvx.core.scene_io.edits
        • simvx.core.scene_io.scene_module
        • simvx.core.scene_io.loader
        • simvx.core.scene_io.detection
        • simvx.core.scene_io.syntax
      • simvx.core.input
        • simvx.core.input.gamepad
        • simvx.core.input.web_events
        • simvx.core.input.state
        • simvx.core.input.router
        • simvx.core.input.map
        • simvx.core.input.events
        • simvx.core.input.enums
      • simvx.core.testing
        • simvx.core.testing.scene_runner
        • simvx.core.testing.recorder
        • simvx.core.testing.optional
        • simvx.core.testing.selftest
        • simvx.core.testing.diagnostics
        • simvx.core.testing.benchmark
        • simvx.core.testing.input_sim
      • simvx.core.navigation3d
        • simvx.core.navigation3d.server
        • simvx.core.navigation3d.nodes
        • simvx.core.navigation3d.mesh
      • simvx.core.nodes_2d
        • simvx.core.nodes_2d.marker
        • simvx.core.nodes_2d.camera
        • simvx.core.nodes_2d.remote_transform
        • simvx.core.nodes_2d.trail
        • simvx.core.nodes_2d.ninepatch
        • simvx.core.nodes_2d.canvas
        • simvx.core.nodes_2d.shapes
        • simvx.core.nodes_2d.node2d
        • simvx.core.nodes_2d.spring_follow
        • simvx.core.nodes_2d.ysort
        • simvx.core.nodes_2d.text
        • simvx.core.nodes_2d.background_bands
        • simvx.core.nodes_2d.path
      • simvx.core.math
        • simvx.core.math.aabb
        • simvx.core.math.rect2
        • simvx.core.math.matrices
        • simvx.core.math.transforms
        • simvx.core.math.raycast
        • simvx.core.math.curves
        • simvx.core.math.types
      • simvx.core.graphics
        • simvx.core.graphics.material
        • simvx.core.graphics.texture
        • simvx.core.graphics.shader_bindings
        • simvx.core.graphics.texture_slot
        • simvx.core.graphics.mesh
        • simvx.core.graphics.shader
      • simvx.core.ai
        • simvx.core.ai.sensor
        • simvx.core.ai.async_slot
        • simvx.core.ai.blackboard
        • simvx.core.ai.agent_node
        • simvx.core.ai.brain
      • simvx.core.debug
        • simvx.core.debug.ui_inspector
        • simvx.core.debug.overlay
        • simvx.core.debug.profiler
      • simvx.core.lsp
        • simvx.core.lsp.protocol
        • simvx.core.lsp.server
        • simvx.core.lsp.client
      • simvx.core.animation
        • simvx.core.animation.tween
        • simvx.core.animation.skeletal
        • simvx.core.animation.state_machine
        • simvx.core.animation.sprite
        • simvx.core.animation.player
        • simvx.core.animation.track
        • simvx.core.animation.blend_space
      • simvx.core.nodes_3d
        • simvx.core.nodes_3d.chase_camera
        • simvx.core.nodes_3d.marker
        • simvx.core.nodes_3d.camera
        • simvx.core.nodes_3d.lights
        • simvx.core.nodes_3d.node3d
        • simvx.core.nodes_3d.remote_transform
        • simvx.core.nodes_3d.multimesh
        • simvx.core.nodes_3d.spring_arm
        • simvx.core.nodes_3d.sprite
        • simvx.core.nodes_3d.text
        • simvx.core.nodes_3d.mesh
        • simvx.core.nodes_3d.path
      • simvx.core.physics
        • simvx.core.physics.builtin
          • simvx.core.physics.builtin.world2d
          • simvx.core.physics.builtin.world
        • simvx.core.physics.pymunk_backend
        • simvx.core.physics.material
        • simvx.core.physics.shapes2d
        • simvx.core.physics.nodes
        • simvx.core.physics.capability
        • simvx.core.physics.shapes
        • simvx.core.physics.world2d
        • simvx.core.physics.slide
        • simvx.core.physics.root
        • simvx.core.physics.nodes2d
        • simvx.core.physics.backends
        • simvx.core.physics.query2d
        • simvx.core.physics.world
        • simvx.core.physics.query
      • simvx.core.audio_backend
      • simvx.core.audio_synth
      • simvx.core.mesh_builder
      • simvx.core.water
      • simvx.core.particle_trail
      • simvx.core.mesh_lod
      • simvx.core.scene_target_graph
      • simvx.core.git_status
      • simvx.core.gpu_particles
      • simvx.core.planar_reflection
      • simvx.core.scene_tree
      • simvx.core.event_bus
      • simvx.core.branding
      • simvx.core.clipboard
      • simvx.core.shortcuts
      • simvx.core.decal
      • simvx.core.i18n
      • simvx.core.atlas
      • simvx.core.hot_reload
      • simvx.core.ocean
      • simvx.core.colour
      • simvx.core.save_manager
      • simvx.core.run
      • simvx.core.descriptors
      • simvx.core.resource
      • simvx.core.env_sync_spec
      • simvx.core.project
      • simvx.core.file_state
      • simvx.core.audio_bus
      • simvx.core.clustered_lighting
      • simvx.core.easing
      • simvx.core.config
      • simvx.core.selection
      • simvx.core.rain
      • simvx.core.irradiance_volume
      • simvx.core.node
      • simvx.core.gesture
      • simvx.core.document
      • simvx.core.properties
      • simvx.core.undo
      • simvx.core.skeleton2d
      • simvx.core.gizmo
      • simvx.core.shell_node
      • simvx.core.decorators
      • simvx.core.light2d
      • simvx.core.mesh_instance_2d
      • simvx.core.audio_errors
      • simvx.core.procedural_sky
      • simvx.core.cli
      • simvx.core.audio_effect
      • simvx.core.signals
      • simvx.core.noise
      • simvx.core.skeleton
      • simvx.core.audio_listener
      • simvx.core.audio_protocol
      • simvx.core.audio
      • simvx.core.scene_step
      • simvx.core.py_console
      • simvx.core.reflection_probe
      • simvx.core.export
      • simvx.core.tilemap
      • simvx.core.asset_resolver
      • simvx.core.io
      • simvx.core.viewport
      • simvx.core.events
      • simvx.core.fog_volume
      • simvx.core.graphics_quality
      • simvx.core.render_view
      • simvx.core.csg
      • simvx.core.scripted_demo
      • simvx.core.particles
      • simvx.core.coroutines
      • simvx.core.colour_grading
      • simvx.core.world_environment
    • simvx.graphics
      • simvx.graphics.materials
        • simvx.graphics.materials.material
        • simvx.graphics.materials.texture
        • simvx.graphics.materials.custom_shader
        • simvx.graphics.materials.shader_compiler
      • simvx.graphics.assets
        • simvx.graphics.assets.block_decode
        • simvx.graphics.assets.image_loader
        • simvx.graphics.assets.ktx2_loader
        • simvx.graphics.assets.mesh_loader
        • simvx.graphics.assets.cubemap_loader
        • simvx.graphics.assets.scene_import
        • simvx.graphics.assets.dds_loader
      • simvx.graphics.gpu
        • simvx.graphics.gpu.memory
        • simvx.graphics.gpu.multi_device
        • simvx.graphics.gpu.instance
        • simvx.graphics.gpu.queue
        • simvx.graphics.gpu.context
        • simvx.graphics.gpu.pipeline_cache
        • simvx.graphics.gpu.sync
        • simvx.graphics.gpu.descriptors
        • simvx.graphics.gpu.retire
        • simvx.graphics.gpu.secondary_engine
        • simvx.graphics.gpu.timestamp_pool
        • simvx.graphics.gpu.pipeline_compute
        • simvx.graphics.gpu.device
        • simvx.graphics.gpu.swapchain
        • simvx.graphics.gpu.commands
        • simvx.graphics.gpu.capabilities
        • simvx.graphics.gpu.pipeline
      • simvx.graphics.ui
      • simvx.graphics.scene
        • simvx.graphics.scene.camera
        • simvx.graphics.scene.frustum
        • simvx.graphics.scene.draw_batch
      • simvx.graphics.shaders
      • simvx.graphics.picking
        • simvx.graphics.picking.pick_pass
        • simvx.graphics.picking.raycast
      • simvx.graphics.renderer
        • simvx.graphics.renderer.sub_viewport
        • simvx.graphics.renderer.light_cull_pass
        • simvx.graphics.renderer.decal_pack
        • simvx.graphics.renderer.layer_post
        • simvx.graphics.renderer.draw2d_pass
        • simvx.graphics.renderer.bloom_pass
        • simvx.graphics.renderer.pass_helpers
        • simvx.graphics.renderer.viewport_manager
        • simvx.graphics.renderer.bindless_draw2d_pass
        • simvx.graphics.renderer.gizmo_pass
        • simvx.graphics.renderer.ssgi_pass
        • simvx.graphics.renderer.render_graph
        • simvx.graphics.renderer.pass_orchestrator
        • simvx.graphics.renderer.shadow_data
        • simvx.graphics.renderer.grid_pass
        • simvx.graphics.renderer.reflection_probe_pack
        • simvx.graphics.renderer.shadow_cache
        • simvx.graphics.renderer.hiz_pass
        • simvx.graphics.renderer.render_target
        • simvx.graphics.renderer.scene_renderer
        • simvx.graphics.renderer.shadow_renderer
        • simvx.graphics.renderer.ocean_pack
        • simvx.graphics.renderer.irradiance_volume_pass
        • simvx.graphics.renderer.render_context
        • simvx.graphics.renderer.resource_registry
        • simvx.graphics.renderer.depth_prepass
        • simvx.graphics.renderer.ssao_pass
        • simvx.graphics.renderer.particle_compute
        • simvx.graphics.renderer.environment_sync
        • simvx.graphics.renderer.game_viewport
        • simvx.graphics.renderer.water_pack
        • simvx.graphics.renderer.occlusion_cull
        • simvx.graphics.renderer.skybox_pass
        • simvx.graphics.renderer.ocean_compute
        • simvx.graphics.renderer.ibl_pass
        • simvx.graphics.renderer.velocity_pass
        • simvx.graphics.renderer.buffer_manager
        • simvx.graphics.renderer.ocean_fft
        • simvx.graphics.renderer.point_shadow_pass
        • simvx.graphics.renderer.forward
        • simvx.graphics.renderer.reflection_probe_pass
        • simvx.graphics.renderer.render_thread
        • simvx.graphics.renderer.outline_pass
        • simvx.graphics.renderer.tilemap_pass
        • simvx.graphics.renderer.particle_pass
        • simvx.graphics.renderer.text_pass
        • simvx.graphics.renderer.async_compute
        • simvx.graphics.renderer.pipeline_manager
        • simvx.graphics.renderer.gpu_batch
        • simvx.graphics.renderer.shadow_pass
        • simvx.graphics.renderer.light2d_pass
        • simvx.graphics.renderer.secondary_sru
        • simvx.graphics.renderer.vertex_layouts
        • simvx.graphics.renderer.transparency
        • simvx.graphics.renderer.view_occlusion
        • simvx.graphics.renderer.post_process
        • simvx.graphics.renderer.ssr_pass
        • simvx.graphics.renderer.mesh_registry
        • simvx.graphics.renderer.caster_slots
        • simvx.graphics.renderer.render_packet
        • simvx.graphics.renderer.scene_copy
        • simvx.graphics.renderer.billboard2d_data
        • simvx.graphics.renderer.render_pass
        • simvx.graphics.renderer.fog_volume_pack
        • simvx.graphics.renderer.billboard2d_pass
        • simvx.graphics.renderer.passes
        • simvx.graphics.renderer.overlay_renderer
        • simvx.graphics.renderer.water_pass
        • simvx.graphics.renderer.render_view
        • simvx.graphics.renderer.volumetric_fog_pass
        • simvx.graphics.renderer.custom_post_process
        • simvx.graphics.renderer.ocean_pass
        • simvx.graphics.renderer.colour_grading
        • simvx.graphics.renderer.shadow_math
        • simvx.graphics.renderer.taa_pass
        • simvx.graphics.renderer.tile_types
      • simvx.graphics.render2d
        • simvx.graphics.render2d.clip_scope
        • simvx.graphics.render2d.publish
        • simvx.graphics.render2d.submit
        • simvx.graphics.render2d.cache
        • simvx.graphics.render2d.item_list
        • simvx.graphics.render2d.item_builder
      • simvx.graphics.streaming
        • simvx.graphics.streaming.server
      • simvx.graphics.platform
      • simvx.graphics.playtest_patterns
      • simvx.graphics.text_renderer
      • simvx.graphics.draw2d_texture
      • simvx.graphics.draw2d_text
      • simvx.graphics.engine
      • simvx.graphics.testing
      • simvx.graphics.scene_adapter
      • simvx.graphics.engine_surface
      • simvx.graphics.blend
      • simvx.graphics.gpu_gate
      • simvx.graphics.draw2d_vertex
      • simvx.graphics.playtest
      • simvx.graphics.text_utils
      • simvx.graphics.cook
      • simvx.graphics.frame_loop
      • simvx.graphics.material_slots
      • simvx.graphics.pytest_plugin
      • simvx.graphics.draw2d_transform
      • simvx.graphics.cli
      • simvx.graphics.input_adapter
      • simvx.graphics.app
      • simvx.graphics.draw2d
      • simvx.graphics.draw2d_ops
      • simvx.graphics.debug_draw
      • simvx.graphics.frame_globals
      • simvx.graphics.types
    • simvx.editor
      • simvx.editor.panels
        • simvx.editor.panels.inspector_sections
        • simvx.editor.panels.scene_tree
          • simvx.editor.panels.scene_tree.type_registry
          • simvx.editor.panels.scene_tree.dialogs
          • simvx.editor.panels.scene_tree.panel
        • simvx.editor.panels.repl_panel
        • simvx.editor.panels.asset_browser
        • simvx.editor.panels.inspector_widgets
        • simvx.editor.panels.animation
        • simvx.editor.panels.profiler_panel
        • simvx.editor.panels.scene3d_view
        • simvx.editor.panels.file_browser
        • simvx.editor.panels.play_controls
        • simvx.editor.panels.code_tab
        • simvx.editor.panels.animation_editor
        • simvx.editor.panels.properties
        • simvx.editor.panels.status_bar
        • simvx.editor.panels.section_widgets
        • simvx.editor.panels.anchor_preset_widget
        • simvx.editor.panels.console
        • simvx.editor.panels.scene2d_view
      • simvx.editor.testing
        • simvx.editor.testing.demo_steps
          • simvx.editor.testing.demo_steps.handlers
            • simvx.editor.testing.demo_steps.handlers.inspector
            • simvx.editor.testing.demo_steps.handlers.nodes
            • simvx.editor.testing.demo_steps.handlers.menu
            • simvx.editor.testing.demo_steps.handlers.viewport
          • simvx.editor.testing.demo_steps.steps
      • simvx.editor.command_palette
      • simvx.editor.refactor_inline
      • simvx.editor.autosave
      • simvx.editor.web_export
      • simvx.editor.dialog_message
      • simvx.editor.refactor_extract
      • simvx.editor.unsaved_class_warning_dialog
      • simvx.editor.export_dialog
      • simvx.editor.about_dialog
      • simvx.editor.main
      • simvx.editor.gizmo_manipulator
      • simvx.editor.make_custom_class_dialog
      • simvx.editor.error_nav
      • simvx.editor.theme
      • simvx.editor.play_mode
      • simvx.editor.error_recovery
      • simvx.editor.project_settings_dialog
      • simvx.editor.project
      • simvx.editor.node_ops
      • simvx.editor.workspace_tabs
      • simvx.editor.game_render_hook
      • simvx.editor.project_classes
      • simvx.editor.config
      • simvx.editor.scene_file_ops
      • simvx.editor.state
      • simvx.editor.rename_class_dialog
      • simvx.editor.layout_presets
      • simvx.editor.default_scenes
      • simvx.editor.convert_to_class
      • simvx.editor.welcome
      • simvx.editor.export_controller
      • simvx.editor.input_map_dialog
      • simvx.editor.modal_dialog
      • simvx.editor.project_registry
      • simvx.editor.preferences_dialog
      • simvx.editor.plugin
      • simvx.editor.cli
      • simvx.editor.menus
      • simvx.editor.root
      • simvx.editor.keyboard_nav
      • simvx.editor.scene_diff
      • simvx.editor.app
      • simvx.editor.live_file_ops
      • simvx.editor.save_dialog
      • simvx.editor.extract
      • simvx.editor.save_report_dialog
      • simvx.editor.hints
      • simvx.editor.templates
      • simvx.editor.commands
      • simvx.editor.duplicate_node_dialog
    • simvx.ide
      • simvx.ide.lint
        • simvx.ide.lint.runner
      • simvx.ide.panels
        • simvx.ide.panels.terminal_panel
        • simvx.ide.panels.output_panel
        • simvx.ide.panels.debug_panel
        • simvx.ide.panels.search_panel
        • simvx.ide.panels.file_browser
        • simvx.ide.panels.symbol_outline
        • simvx.ide.panels.problems_panel
        • simvx.ide.panels.settings_panel
      • simvx.ide.dap
        • simvx.ide.dap.client
      • simvx.ide.widgets
        • simvx.ide.widgets.command_palette
        • simvx.ide.widgets.minimap
        • simvx.ide.widgets.confirm_dialog
        • simvx.ide.widgets.status_bar
        • simvx.ide.widgets.goto_line
        • simvx.ide.widgets.autocomplete
      • simvx.ide.lsp
        • simvx.ide.lsp.client
      • simvx.ide.language_server
      • simvx.ide.editor_integration
      • simvx.ide.edit_actions
      • simvx.ide.playtest
      • simvx.ide.config
      • simvx.ide.state
      • simvx.ide.embedded
      • simvx.ide.app
      • simvx.ide.file_tabs
      • simvx.ide.keybindings
      • simvx.ide.debug_session

Project

  • SimVX Documentation License
Back to top
View this page

Menu Bar¶

a desktop-style menu strip with dropdown menus.

▶ Run in browser

Tags: ui menu menubar desktop-ui

A MenuBar pinned to the top of the window with File, Edit and View menus. Each dropdown lists items with shortcut hints (File and Edit group theirs with separators), opens over the content panel below, and closes when an item is chosen. A status label along the bottom edge echoes the last action so every entry is visibly wired up.

What it demonstrates¶

  • MenuBar.add_menu(title, items) building a menu strip from plain data.

  • MenuItem(text=..., callback=..., shortcut=...) and MenuItem(separator=True).

  • Reserving the bar’s fixed height inside a stretching VBoxContainer with MenuBar.BAR_HEIGHT, min_size and stretch_ratio = 0.

  • Dropdowns drawing over the content panel beneath them.

Run: uv run python examples/features/ui/menus.py Headless self-check: uv run python examples/features/ui/menus.py –test

Source¶

  1"""Menu Bar: a desktop-style menu strip with dropdown menus.
  2
  3A `MenuBar` pinned to the top of the window with File, Edit and View menus.
  4Each dropdown lists items with shortcut hints (File and Edit group theirs with
  5separators), opens over the content panel below, and closes when an item is
  6chosen. A status label along
  7the bottom edge echoes the last action so every entry is visibly wired up.
  8
  9# /// simvx
 10# tags = ["ui", "menu", "menubar", "desktop-ui"]
 11# web = { root = "MenuDemo", width = 800, height = 600, responsive = true }
 12# ///
 13
 14## What it demonstrates
 15- `MenuBar.add_menu(title, items)` building a menu strip from plain data.
 16- `MenuItem(text=..., callback=..., shortcut=...)` and `MenuItem(separator=True)`.
 17- Reserving the bar's fixed height inside a stretching `VBoxContainer` with
 18  `MenuBar.BAR_HEIGHT`, `min_size` and `stretch_ratio = 0`.
 19- Dropdowns drawing over the content panel beneath them.
 20
 21Run: uv run python examples/features/ui/menus.py
 22Headless self-check: uv run python examples/features/ui/menus.py --test
 23"""
 24
 25from simvx.core import (
 26    AnchorPreset,
 27    Colour,
 28    Label,
 29    MenuBar,
 30    MenuItem,
 31    Node,
 32    Panel,
 33    SizingMode,
 34    VBoxContainer,
 35    Vec2,
 36)
 37from simvx.graphics import App
 38
 39
 40class MenuDemo(Node):
 41    """Root node for menu bar demo scene."""
 42
 43    def on_ready(self):
 44        root = VBoxContainer(name="Root")
 45        root.set_anchor_preset(AnchorPreset.FULL_RECT)
 46        root.separation = 0
 47        root.sizing = SizingMode.EXPAND
 48        self.add_child(root)
 49
 50        # --- Menu bar (fixed height, full width) ---
 51        menubar = MenuBar(name="menubar")
 52        menubar.min_size = Vec2(0, MenuBar.BAR_HEIGHT)
 53        menubar.stretch_ratio = 0.0
 54        root.add_child(menubar)
 55
 56        status = Label("Ready")
 57        status.text_colour = Colour.LIGHT_GRAY
 58
 59        def make_action(label):
 60            def handler():
 61                status.text = f"Action: {label}"
 62
 63            return handler
 64
 65        # File menu
 66        menubar.add_menu(
 67            "File",
 68            [
 69                MenuItem(text="New", callback=make_action("New"), shortcut="Ctrl+N"),
 70                MenuItem(text="Open", callback=make_action("Open"), shortcut="Ctrl+O"),
 71                MenuItem(text="Save", callback=make_action("Save"), shortcut="Ctrl+S"),
 72                MenuItem(separator=True),
 73                MenuItem(text="Quit", callback=lambda: self.app.quit(), shortcut="Ctrl+Q"),
 74            ],
 75        )
 76
 77        # Edit menu
 78        menubar.add_menu(
 79            "Edit",
 80            [
 81                MenuItem(text="Undo", callback=make_action("Undo"), shortcut="Ctrl+Z"),
 82                MenuItem(text="Redo", callback=make_action("Redo"), shortcut="Ctrl+Y"),
 83                MenuItem(separator=True),
 84                MenuItem(text="Cut", callback=make_action("Cut"), shortcut="Ctrl+X"),
 85                MenuItem(text="Copy", callback=make_action("Copy"), shortcut="Ctrl+C"),
 86                MenuItem(text="Paste", callback=make_action("Paste"), shortcut="Ctrl+V"),
 87            ],
 88        )
 89
 90        # View menu
 91        menubar.add_menu(
 92            "View",
 93            [
 94                MenuItem(text="Zoom In", callback=make_action("Zoom In"), shortcut="Ctrl++"),
 95                MenuItem(text="Zoom Out", callback=make_action("Zoom Out"), shortcut="Ctrl+-"),
 96                MenuItem(text="Reset Zoom", callback=make_action("Reset Zoom"), shortcut="Ctrl+0"),
 97            ],
 98        )
 99
100        # --- Main content panel (takes the remaining window height) ---
101        content = Panel(name="ContentPanel")
102        content.bg_colour = Colour.hex("#1A1A2E")
103        root.add_child(content)
104
105        center_label = Label("Click File, Edit or View to open a menu")
106        center_label.text_colour = Colour.GRAY
107        center_label.font_size = 16.0
108        center_label.set_anchor_preset(AnchorPreset.CENTER)
109        center_label.margin_left = -220
110        center_label.margin_right = 220
111        center_label.margin_top = -15
112        center_label.margin_bottom = 15
113        center_label.alignment = "center"
114        content.add_child(center_label)
115
116        # --- Status bar ---
117        status.set_anchor_preset(AnchorPreset.BOTTOM_WIDE)
118        status.margin_left = 10
119        status.margin_right = 10
120        status.margin_top = -30
121        status.margin_bottom = -10
122        content.add_child(status)
123
124
125def _selftest() -> bool:
126    """Headless: open the menus by clicking their titles and choose items by row.
127
128    A title is found where the bar draws it, so the click lands on the strip the
129    user aims at rather than at a computed guess; an item is clicked at the row the
130    open popup occupies, from its own rect and ``item_height``. The status label is
131    the demo's one output and every assertion reads it back.
132    """
133    from simvx.core.ui.testing import UITestHarness
134
135    harness = UITestHarness(MenuDemo(name="MenuDemo"), screen_size=(800, 600))
136    ok = True
137
138    def check(label: str, passed: bool, detail: str) -> None:
139        nonlocal ok
140        ok = ok and passed
141        print(f"{'ok  ' if passed else 'FAIL'} {label}: {detail}")
142
143    harness.tick()
144    menubar = harness.find_by_name("menubar")
145    status = harness.find_by_text("Ready")
146    _, bar_y, _, bar_h = menubar.get_global_rect()
147
148    def title_point(name: str) -> tuple[float, float]:
149        """The middle of the bar strip where ``name`` is drawn."""
150        drawn = next(c for c in harness.draw_log.calls_of_type("text") if c.text == name)
151        return (drawn.x + 2, bar_y + bar_h / 2)
152
153    def open_menu(name: str):
154        harness.click(title_point(name))
155        harness.tick()
156        return next(popup for title, popup in menubar.menus if title == name)
157
158    def click_item(popup, index: int) -> None:
159        gx, gy, gw, _ = popup.get_global_rect()
160        harness.click((gx + gw / 2, gy + popup.item_height * (index + 0.5)))
161        harness.tick()
162
163    check(
164        "the bar reserves its own fixed height and lists all three menus",
165        bar_h == MenuBar.BAR_HEIGHT and [title for title, _ in menubar.menus] == ["File", "Edit", "View"],
166        f"{bar_h:.0f}px bar: " + ", ".join(title for title, _ in menubar.menus),
167    )
168
169    file_menu = open_menu("File")
170    check(
171        "clicking a title drops its menu open below the bar",
172        file_menu.visible and file_menu.get_global_rect()[1] >= bar_y + bar_h,
173        f"File popup at y={file_menu.get_global_rect()[1]:.0f}, below a bar ending at {bar_y + bar_h:.0f}",
174    )
175
176    click_item(file_menu, 2)  # Save
177    check(
178        "choosing an item runs its callback and closes the menu",
179        status.text == "Action: Save" and not file_menu.visible,
180        f"{status.text!r}, popup visible = {file_menu.visible}",
181    )
182
183    # A separator is a row that draws but does nothing: clicking it must leave the
184    # status line where it was, while still dismissing the menu like any click.
185    file_menu = open_menu("File")
186    separator = next(i for i, item in enumerate(file_menu.items) if item.separator)
187    click_item(file_menu, separator)
188    check(
189        "clicking a separator changes nothing but still closes the menu",
190        status.text == "Action: Save" and not file_menu.visible,
191        f"row {separator} of File left the status at {status.text!r}",
192    )
193
194    # Hovering a different title while one menu is open switches to it, which is
195    # the behaviour a desktop menu strip is expected to have.
196    file_menu = open_menu("File")
197    harness.mouse_move(title_point("Edit"))
198    harness.tick()
199    edit_menu = next(popup for title, popup in menubar.menus if title == "Edit")
200    check(
201        "hovering another title while a menu is open switches the open menu",
202        edit_menu.visible and not file_menu.visible,
203        f"File {file_menu.visible}, Edit {edit_menu.visible}",
204    )
205
206    click_item(edit_menu, 4)  # Copy, past Edit's separator
207    check(
208        "and the second menu's items are wired up just as the first's are",
209        status.text == "Action: Copy",
210        status.text,
211    )
212
213    view_menu = open_menu("View")
214    check(
215        "every item carries the shortcut hint it was given",
216        [item.shortcut for item in view_menu.items] == ["Ctrl++", "Ctrl+-", "Ctrl+0"],
217        ", ".join(f"{item.text} {item.shortcut}" for item in view_menu.items),
218    )
219    harness.click((400.0, 400.0))  # anywhere off the chain dismisses it
220    harness.tick()
221    check(
222        "clicking away from the bar dismisses the open menu",
223        not view_menu.visible,
224        f"View popup visible = {view_menu.visible}",
225    )
226
227    harness.teardown()
228    print("SELFTEST:", "PASS" if ok else "FAIL")
229    return ok
230
231
232if __name__ == "__main__":
233    import sys
234
235    if "--test" in sys.argv:
236        sys.exit(0 if _selftest() else 1)
237    app = App(title="SimVX Menu Demo", width=800, height=600)
238    app.run(MenuDemo())
Next
Minimap
Previous
Grid Inventory
Copyright © 2026, SimVX Contributors
Made with Sphinx and @pradyunsg's Furo
On this page
  • Menu Bar
    • What it demonstrates
    • Source