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¶
Manages the run/pause/stop lifecycle for previewing games in the editor. |
Data¶
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_enabledAND, when a play session is active, the live :class:HotReloadManagerso 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.
- 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.
- attach_profiler(profiler: simvx.core.debug.profiler.FrameProfiler | None) None[source]¶
Attach (or detach) a :class:
FrameProfilerfor play-mode metrics.When attached, :meth:
updatetimes each phase (physics,process,ui,total) and samples per-node timings into the profiler. The profiler also drives the editor’s profiler panel.
- 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 usingInput.is_action_pressed()transparently see the game’s isolated input without swapping the global Input singleton.
- forward_input_to_game(event_type: str, **kwargs) None[source]¶
Forward an input event from the viewport into the running game.
Called by the editor when the user interacts within the viewport during play mode. The event goes through the same :class:
InputRoutera windowed game’s platform backend uses, so all three consequences of an input event happen and happen in the engine’s own order: the game’s isolatedInputstate is updated, UI widgets are routed the event with focus, hover and hit-testing, and aTreeInputEventis propagated so@on_inputhandlers in the game run.That last one is why the router is here rather than a hand-written state write: a game’s decorated input handlers used to be unreachable in play mode, because nothing on this path ever propagated a tree event.
Args: event_type: One of
"key","mouse_button","mouse_move","scroll","char". **kwargs: Event-specific data (see below).Key events:
key=int,pressed=bool. Akey_nameis accepted and ignored: the router derives the widget-facing name from the keycode through the same map every backend uses. Mouse button:button=int,pressed=boolMouse move:x=float,y=float,viewport_size=(vw, vh)(optional): when provided,(x, y)are scaled bygame_screen_size / viewport_sizeso a click on the editor’s viewport rect lands at the matching position in the game tree’s UI space. Without it, coordinates are forwarded as-is. Scroll:dx=float,dy=floatChar events:char=str
- 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.
- 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_framesconsecutive frames so we don’t churn GPU memory every frame. The first call after viewport creation seeds the baseline without triggering a resize.
- 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.