simvx.editor.play_mode

Play Mode: Run/pause/stop lifecycle for in-editor game preview.

Manages scene serialization/restoration, camera switching, input routing, and per-frame process/physics updates during play mode. The game runs in a separate SceneTree with isolated input state so editor and game input never interfere.

Usage: play_mode = PlayMode(editor_state) play_mode.start() # F5: serialize scene, begin processing play_mode.toggle_pause() # F7: pause/resume processing play_mode.stop() # F6: restore pre-play scene state

# Called each frame by the editor's main loop:
play_mode.update(dt)

Module Contents

Classes

PlayMode

Manages the run/pause/stop lifecycle for previewing games in the editor.

Data

log

API

simvx.editor.play_mode.log

‘getLogger(…)’

class simvx.editor.play_mode.PlayMode(state: simvx.editor.state.State)[source]

Manages the run/pause/stop lifecycle for previewing games in the editor.

The game scene runs in an isolated SceneTree with its own input state. The editor’s process loop calls update(dt) every frame to drive the game cooperatively (no threading).

Initialization

start() → None[source]

Begin play mode (triggered by F5).

Serializes the current scene so it can be restored on stop, creates an isolated game tree with its own input state, and calls on_ready() on all game nodes.

set_hot_reload_enabled(enabled: bool) → None[source]

Enable or disable script hot-reload during play mode.

Updates :attr:State.hot_reload_enabled AND, when a play session is active, the live :class:HotReloadManager so the change takes effect immediately without restarting PlayMode.

toggle_pause() → None[source]

Toggle pause during play mode (triggered by F7).

When paused, process/physics updates are skipped but the scene continues to render so the user can inspect the frozen state.

Pausing stops forwarding: the viewport’s :class:SceneHost turns forwarding off, which is a handover and not a switch, so a key down at the moment of the pause does not stay down for ever and walk the character into a wall on resume. The key itself is still under the player’s finger and device state goes on saying so.

stop() → None[source]

Stop play mode and restore the pre-play scene (triggered by F6).

Destroys the game tree and input state, deserializes the saved snapshot back into the editor’s scene tree.

start_detached() → None[source]

Start the game in a separate OS window via subprocess.

stop_detached() → None[source]

Stop the detached game window if running.

property is_detached: bool[source]

Whether a detached game process is running.

attach_profiler(profiler: simvx.core.debug.profiler.FrameProfiler | None) → None[source]

Attach (or detach) a :class:FrameProfiler for play-mode metrics.

When attached, :meth:update times each phase (physics, process, ui, total) and samples per-node timings into the profiler. The profiler also drives the editor’s profiler panel.

The per-node timings come from the engine’s own frame walk, which is the only thing that knows it: timing a walk of our own would mean running one, and the engine’s does considerably more than visit nodes. The walk observer is process-wide, so it is installed only while the game tree is being stepped (see :meth:_step_game); installed for longer, it would also time the editor’s own nodes and report them as the game’s.

property profiler: simvx.core.debug.profiler.FrameProfiler | None[source]
update(dt: float) → None[source]

Per-frame update, called by the editor’s process loop.

When playing and not paused, processes the game tree under its own per-tree input (game_tree.activate_input()), so game scripts using Input.pressed() transparently see the game’s isolated input without swapping the global Input singleton.

should_route_input_to_game() → bool[source]

Return True when viewport input events should be forwarded to the game.

Editor-global shortcuts (F5/F6/F7) are always processed by the editor regardless of this flag.

property game_tree: simvx.core.SceneTree | None[source]

The game’s isolated SceneTree, or None when not playing.

property game_input[source]

The game’s isolated per-tree input state (a _Input), or None when not playing.

property game_texture_id: int | None[source]

Bindless texture ID of the game viewport, or None if not available.

Returns a valid texture ID when the game viewport renderer is active and ready. The viewport panel checks this to decide whether to display a GPU-rendered game view or fall back to wireframe.

property game_viewport[source]

The GameViewportRenderer instance, or None.

create_game_viewport(engine, width: int, height: int) → None[source]

Create the offscreen game viewport renderer.

Called by Root when play mode starts and a graphics engine is available.

resize_game_viewport(width: int, height: int) → None[source]

Resize the offscreen game viewport immediately (no debounce).

ensure_game_viewport_size(width: int, height: int, *, debounce_frames: int = 6) → None[source]

Debounced live resize hook called from the viewport panel each frame.

During a splitter drag the panel size changes many frames in a row. Only resize once the target size has been stable for debounce_frames consecutive frames so we don’t churn GPU memory every frame. The first call after viewport creation seeds the baseline without triggering a resize.

destroy_game_viewport() → None[source]

Destroy the offscreen game viewport renderer.

get_active_camera() → simvx.core.Camera3D | None[source]

Return the camera that should drive the viewport.

During play mode the game’s own Camera3D is used. Outside of play mode the editor’s orbit camera is returned.

get_border_colour() → tuple[float, float, float, float] | None[source]

Return a viewport border colour indicating the current play state.

  • Green (0.2, 0.8, 0.2, 1.0) – game is running.

  • Orange (1.0, 0.6, 0.0, 1.0) – game is paused.

  • None – editor is in normal (stopped) mode.

property elapsed_time: float[source]

Seconds elapsed since play mode started.

property frame_count: int[source]

Number of frames processed since play mode started.

property is_active: bool[source]

Convenience: True when the game is playing (paused or not).