Export venues as editor-authorable .tres resources
- tools/export_venues.gd (SceneTree script) saves the three factory scenarios to content/venues/<id>.tres via ResourceSaver. The factory stays the source of truth; the exported files are what an editor workflow would edit and ship. - New tests load the files back and check that id, name, event pool, profiles, policy (ID/wand), equipment, door-staff lines, shift phases, and locations all survive. They also fail when the exported files are missing or stale, so the export is re-run after content changes. - GUT is consciously not adopted: the custom headless runner already covers 157 assertions without an editor plugin and keeps CI dependency-free. Recorded in DONE.md. - TODO: the planned backlog is complete; only optional future ideas remain. - README/MEMORY updated. Version 0.2.16.
This commit is contained in:
1 parent
72b9378e69
commit
f763cff744
10 files changed
+2318
-9
No files matched your search
@@ -0,0 +1,62 @@
|
||||
extends RefCounted
|
||||
## Venues can be authored as `.tres` resources: the built-in factories export and
|
||||
## round-trip without losing their data (optional editor workflow, TODO tooling).
|
||||
|
||||
const Factory := preload("res://src/content/scenario_factory.gd")
|
||||
const Rules := preload("res://src/core/rules.gd")
|
||||
const VenueScenario := preload("res://src/core/venue_scenario.gd")
|
||||
|
||||
func test_venues_round_trip_through_tres() -> bool:
|
||||
var scenarios := [Factory.hollywood_building(), Factory.joke_shop(), Factory.tv_studio()]
|
||||
for scenario in scenarios:
|
||||
var path := "user://%s_roundtrip.tres" % scenario.id
|
||||
var err: int = ResourceSaver.save(scenario, path)
|
||||
if err != OK:
|
||||
return TestUtils.fail("could not save %s (error %d)" % [scenario.id, err])
|
||||
var loaded = ResourceLoader.load(path)
|
||||
if not (loaded is VenueScenario):
|
||||
return TestUtils.fail("%s did not load back as VenueScenario" % scenario.id)
|
||||
var a := TestUtils.check_eq(loaded.id, scenario.id, "%s id survives" % scenario.id)
|
||||
var b := TestUtils.check_eq(loaded.display_name, scenario.display_name, "%s name survives" % scenario.id)
|
||||
var c := TestUtils.check_eq(loaded.event_pool.size(), scenario.event_pool.size(), "%s event pool survives" % scenario.id)
|
||||
var d := TestUtils.check_eq(loaded.npc_profiles.size(), scenario.npc_profiles.size(), "%s profiles survive" % scenario.id)
|
||||
var e := TestUtils.check_eq(loaded.waypoint_for_intent("sit"), scenario.waypoint_for_intent("sit"), "%s locations survive" % scenario.id)
|
||||
if not (a and b and c and d and e):
|
||||
return false
|
||||
return true
|
||||
|
||||
func test_exported_tres_files_match_the_factory() -> bool:
|
||||
## content/venues/*.tres is generated by tools/export_venues.gd; make sure it is
|
||||
## present and not stale relative to the factory.
|
||||
for scenario in [Factory.hollywood_building(), Factory.joke_shop(), Factory.tv_studio()]:
|
||||
var path := "res://content/venues/%s.tres" % scenario.id
|
||||
if not FileAccess.file_exists(path):
|
||||
return TestUtils.fail("missing exported venue %s — run tools/export_venues.gd" % path)
|
||||
var loaded = ResourceLoader.load(path)
|
||||
if not (loaded is VenueScenario):
|
||||
return TestUtils.fail("%s is not a VenueScenario" % path)
|
||||
if loaded.event_pool.size() != scenario.event_pool.size():
|
||||
return TestUtils.fail("%s is stale (events %d vs %d) — re-run tools/export_venues.gd" % [
|
||||
path, loaded.event_pool.size(), scenario.event_pool.size()])
|
||||
if not TestUtils.check_eq(loaded.shift_duration_s, scenario.shift_duration_s, "%s duration matches" % scenario.id):
|
||||
return false
|
||||
return true
|
||||
|
||||
func test_exported_policy_and_events_intact() -> bool:
|
||||
var loaded = ResourceLoader.load("res://content/venues/joke_shop.tres")
|
||||
var a := TestUtils.check(loaded != null and loaded.access_policy != null, "access policy survives export")
|
||||
var b := TestUtils.check_eq(loaded.access_policy.require_id, true, "joke shop still requires ID")
|
||||
var c := TestUtils.check_eq(loaded.access_policy.wand_screening_required, true, "wand screening still required")
|
||||
var d := TestUtils.check_eq(loaded.equipment.has("wand"), true, "equipment survives export")
|
||||
var ids: Array = []
|
||||
for event in loaded.event_pool:
|
||||
ids.append(str((event as Dictionary).get("id", "")))
|
||||
var e := TestUtils.check(ids.has("joke_refuses_wand"), "authored events survive export")
|
||||
var f := TestUtils.check(loaded.door_staff_lines.has("refusal"), "door-staff lines survive export")
|
||||
return a and b and c and d and e and f
|
||||
|
||||
func test_exported_phases_survive() -> bool:
|
||||
var loaded = ResourceLoader.load("res://content/venues/hollywood_building.tres")
|
||||
var a := TestUtils.check(loaded.shift_phases.has(Rules.Phase.LATE), "late phase survives export")
|
||||
var b := TestUtils.check_eq(int(loaded.shift_phases[Rules.Phase.LATE].get("start_s", -1)), 700, "late start preserved")
|
||||
return a and b
|
||||
Reference in new issue
Block a user