ajhahn.de
← Theria commits

Commit

Theria

fix: dev runs play source, not the installed payload

ajhahnde · Jun 2026 · 96722f092ed89ba91f0fff32b92f39dbf18a6213 · parent: ff3b635 · view on GitHub →

modified src/client/boot.gd
@@ -113,7 +113,11 @@ func _finish(status: String, message: String) -> void:
## runs the seed it shipped with. A failed pack load is non-fatal for the same reason — the
## bundled scene is still there to fall back to.
func _hand_off() -> void:
if UpdateManifest.has_payload():
# Only an exported player build runs the installed payload. An editor/source run (F5, or
# `godot --path .`, including the `--local`/`--host`/`--join` dev launches) must play its own
# `res://` source, never the last-downloaded pck — otherwise it silently shadows uncommitted
# changes with the shipped build, which is exactly the trap that hid the HUD during playtests.
if UpdateManifest.should_load_payload(OS.has_feature("editor"), UpdateManifest.has_payload()):
ProjectSettings.load_resource_pack(UpdateManifest.PCK_PATH)
# Deferred: a skip-path hand-off runs inside `_ready`, when the tree is mid-add and a
# synchronous scene change is refused; deferring runs it on the next idle frame instead.
modified src/update/update_manifest.gd
@@ -167,6 +167,16 @@ static func has_payload() -> bool:
return FileAccess.file_exists(PCK_PATH)
## Whether the boot scene should load the installed payload pck over the bundled files. Only an
## exported player build may: an editor/source run (`is_editor`) must play its own `res://`
## source even when a payload is present, or the last-downloaded shipped pck silently shadows
## uncommitted changes — the trap that made a freshly-built HUD look like it would not render.
## Pure (takes the two facts as arguments) so the rule is unit-testable without a real pck or
## the editor feature flag.
static func should_load_payload(is_editor: bool, payload_present: bool) -> bool:
return payload_present and not is_editor
## The GitHub releases-API path segment a channel resolves to, appended to
## `repos/<owner>/<name>/`. Beta names the rolling pre-release by its tag; Stable asks for
## `releases/latest`, which GitHub defines as the newest non-prerelease, non-draft release
modified test/unit/test_update_manifest.gd
@@ -113,6 +113,24 @@ func test_release_path_falls_back_to_beta_for_an_unknown_channel() -> void:
)
func test_should_load_payload_only_in_an_exported_build() -> void:
# An editor/source run must play its own res:// source even with a payload present, or the
# last-downloaded shipped pck shadows uncommitted changes (the HUD-not-rendering trap). Only a
# non-editor (exported) build with a payload installed loads it.
assert_true(
UpdateManifest.should_load_payload(false, true),
"an exported build with a payload installed loads it"
)
assert_false(
UpdateManifest.should_load_payload(true, true),
"an editor/source run ignores the payload and plays its own source"
)
assert_false(
UpdateManifest.should_load_payload(false, false),
"no payload, nothing to load"
)
func test_normalize_channel_coerces_to_a_known_id() -> void:
assert_eq(UpdateManifest.normalize_channel("stable"), UpdateManifest.CHANNEL_STABLE)
assert_eq(UpdateManifest.normalize_channel("beta"), UpdateManifest.CHANNEL_BETA)