🔥 Hot reloading
While debugging my game, I want to change things in Pandora and see them reflected in my game instantly. Currently, you have to restart the game in order for changes to take effect.
Hi @bitbrain 👋
I'd like to help implement hot-reloading for Pandora and have put together a small prototype to start the conversation.
Proposed approach
-
File watcher node (
file_watcher.gd)@tool class_name PandoraFileWatcher extends Node signal file_changed(file_path: String) var _watched_file: String var _last_modified_time: int = 0 var _check_timer := Timer.new() var _debounce_timer := Timer.new() func _ready() -> void: _check_timer.wait_time = 0.5 _check_timer.autostart = true _check_timer.timeout.connect(_check_file_changes) add_child(_check_timer) _debounce_timer.wait_time = 0.2 _debounce_timer.one_shot = true _debounce_timer.timeout.connect(_emit_file_changed) add_child(_debounce_timer) func watch_file(file_path: String) -> void: _watched_file = file_path if FileAccess.file_exists(_watched_file): _last_modified_time = FileAccess.get_modified_time(_watched_file) func _check_file_changes() -> void: if _watched_file.is_empty() or not FileAccess.file_exists(_watched_file): return var current_time = FileAccess.get_modified_time(_watched_file) if current_time > _last_modified_time: _last_modified_time = current_time _debounce_timer.start() func _emit_file_changed() -> void: file_changed.emit(_watched_file) -
Integrate in
api.gdsignal data_reloaded var _file_watcher := PandoraFileWatcher.new() add_child(_file_watcher) _file_watcher.file_changed.connect(_on_data_file_changed) _file_watcher.watch_file(data_path) func _on_data_file_changed(_fp: String) -> void: reload_data() func reload_data() -> void: if not _loaded: return _clear() load_data() data_reloaded.emit()
Questions & next steps
- Scope – Is watching a single data file enough for the first iteration, or do we also want to monitor entire folders / other asset types?
- Performance – A 0.5s polling interval feels responsive in practice, but I can expose it as an export var if you'd prefer configurability.
- Debounce – I added a 0.2s debounce to avoid double-fires on rapid saves; let me know if that should be tuned differently.
-
API surface – Are the
file_changedanddata_reloadedsignals the hooks you had in mind, or would you like a different design?
If this direction looks good I'm happy to polish it and open a PR.
Thanks, and let me know what you think!
Feel free to create a PR and I can leave specific feedback on the code itself. This is a great start!
One issue I can see is object referencing: after reloading the data, objects in the game may still have their old objects initialized, so the new state is not reflected in-game. To make matters more complex, there are also "entity instances" that should automatically receive those changes.