simvx.core.hot_reload

Hot-reload system – watch script files for changes and reload them live.

On file change: serialize node state -> importlib.reload(module) -> instantiate new class -> restore state. Non-serializable state is warned and skipped.

Public API: from simvx.core.hot_reload import HotReloadManager

mgr = HotReloadManager(tree)
mgr.watch("game.py")          # start watching a module file
mgr.poll()                    # call each frame (or on a timer)

Module Contents

Classes

HotReloadManager

Watches script files for changes and hot-reloads node classes.

Data

API

simvx.core.hot_reload.log

‘getLogger(…)’

simvx.core.hot_reload.__all__

[‘HotReloadManager’]

class simvx.core.hot_reload.HotReloadManager(tree: simvx.core.scene_tree.SceneTree, poll_interval: float = 0.5)[source]

Watches script files for changes and hot-reloads node classes.

Usage: mgr = HotReloadManager(tree) mgr.watch(“my_game.py”) # In your game loop: mgr.poll() # checks every poll_interval seconds

Attributes: enabled (bool): When False, :meth:poll returns immediately without checking files or reloading. Watched files are retained so toggling enabled back to True resumes change detection from the next poll. force_reload and reload_module ignore enabled.

Signals: module_reloaded(module_name: str, class_names: list[str]) Emitted after a module is successfully reloaded and live nodes updated.

reload_failed(module_name: str, error: str)
    Emitted when a reload attempt fails. The old version remains active.

node_reinstanced(old_node: Node, new_node: Node)
    Emitted when a node is replaced with a fresh instance of its (reloaded) class.

Initialization

watch(file_path: str) None[source]

Start watching a Python file for changes.

Args: file_path: Path to a .py file. The corresponding module must be importable.

unwatch(file_path: str) None[source]

Stop watching a file.

property watched_files: list[str][source]

Return list of currently watched file paths.

poll(dt: float = 0.0) list[str][source]

Check watched files for changes. Call each frame with delta time.

Returns an empty list immediately when :attr:enabled is False, so the per-frame call site stays cheap when hot reload is toggled off.

Returns: List of module names that were reloaded.

force_reload(module_name: str) bool[source]

Force-reload a specific module by name.

Returns: True if reload succeeded, False otherwise.

reload_module(file_path: str) bool[source]

Reload a module by its file path.

Reimports the module, finds changed classes, and updates live nodes. On failure, keeps the old version and emits reload_failed.

Args: file_path: Path to the .py file to reload.

Returns: True if reload succeeded, False otherwise.

reinstance_node(old_node: simvx.core.node.Node, new_class: type[simvx.core.node.Node]) simvx.core.node.Node[source]

Create a new instance of new_class, copying state and children from old_node.

The new node replaces old_node in the tree (same parent, same position among siblings). Clears any _script_error flag so processing resumes.

Emits node_reinstanced(old_node, new_node).

Returns: The newly created node.