Rebuild the Joke Shop as the Sunset Strip block
- Replace the alley with the 27 m Comedy Store-inspired hall, signature canopy, circular blade sign, red curtain bays, west entrance, low-rise neighbours, dry hillside and opposite frontage. - Add day/night/across-street concept frames and real-site mapping notes. - Expose the Joke Shop day stage in the realism captures and refresh the gallery shots. - Render multiline HUD/wand strings correctly and list carried items in the wand panel. - Add the Joke Shop layout/budget tests and update docs, roadmap and changelog.
This commit is contained in:
1 parent
74dc1fdc1d
commit
37f925c7ad
39 files changed
+1015
-96
No files matched your search
@@ -12,7 +12,14 @@ func test_strings_lookup() -> bool:
|
||||
func test_strings_format() -> bool:
|
||||
var a := TestUtils.check_eq(Strings.fmt("react.comply", ["Tourist"]), "Tourist complies and steps back.", "reaction formats")
|
||||
var b := TestUtils.check_eq(Strings.fmt("hud.venue_switched", ["The Joke Shop"]), "Venue: The Joke Shop", "venue switch formats")
|
||||
return a and b
|
||||
# JSON needs one escaped newline; two backslashes used to reach the HUD as a
|
||||
# literal "\n" in the shift status and wand panel.
|
||||
var status := Strings.lookup("hud.shift_status")
|
||||
var c := TestUtils.check(status.contains("\n") and not status.contains("\\n"),
|
||||
"multiline HUD strings use real newlines")
|
||||
var d := TestUtils.check_eq(Strings.fmt("hud.wand_items", ["Keys, Phone"]),
|
||||
"Carried items: Keys, Phone", "wand item list formats")
|
||||
return a and b and c and d
|
||||
|
||||
func test_strings_json_backed_all_resolve() -> bool:
|
||||
## Every key in the JSON-loaded table must resolve to a value other than
|
||||
@@ -92,6 +99,7 @@ func test_strings_cover_ui_keys() -> bool:
|
||||
var required := [
|
||||
"hud.controls", "hud.escalation_prefix", "hud.cooldown", "hud.venue_switched",
|
||||
"hud.aim_first", "hud.no_one_nearby", "hud.targeting", "hud.no_wand",
|
||||
"hud.wand_items", "hud.shift_status",
|
||||
"hud.screen_first", "access.granted", "access.denied", "access.policy_satisfied",
|
||||
"access.wrong_grant", "access.wrong_deny", "wand.admitted_prohibited",
|
||||
"wand.denied_false_alarm", "wand.cleared", "wand.refused", "wand.recharge", "radio.address_first",
|
||||
|
||||
@@ -27,7 +27,7 @@ func test_venue_geometry_specs_are_distinct_and_defaulted() -> bool:
|
||||
var a := TestUtils.check(hollywood.venue_id == "hollywood_building",
|
||||
"the default venue is Hollywood")
|
||||
var b := TestUtils.check(float(hollywood.spec["facade_width"]) > float(joke.spec["facade_width"]),
|
||||
"the Joke Shop alley is narrower than the boulevard")
|
||||
"the Joke Shop frontage is slightly narrower than the boulevard")
|
||||
var c := TestUtils.check(not bool(joke.spec["features"]["skyline"])
|
||||
and not bool(joke.spec["features"]["marquee"]),
|
||||
"the Joke Shop disables the skyline and marquee")
|
||||
@@ -41,8 +41,11 @@ func test_venue_geometry_specs_are_distinct_and_defaulted() -> bool:
|
||||
builder.build()
|
||||
var body := root.find_child("Building", true, false)
|
||||
var facade := body.get_child(0) as MeshInstance3D if body != null else null
|
||||
var f := TestUtils.check(facade != null and (facade.mesh as BoxMesh).size.x < 20.0,
|
||||
"the Joke Shop builds the narrow facade")
|
||||
var f := TestUtils.check(facade != null
|
||||
and str(builder.spec.get("architecture", "")) == "comedy_store"
|
||||
and (facade.mesh as BoxMesh).size.x > 24.0
|
||||
and (facade.mesh as BoxMesh).size.x < 30.0,
|
||||
"the Joke Shop builds its 27 m Sunset frontage")
|
||||
var g := TestUtils.check(root.find_child("SkylineBackdrop", true, false) == null,
|
||||
"the Joke Shop builds no skyline ring")
|
||||
hollywood.root.free()
|
||||
@@ -53,6 +56,47 @@ func test_venue_geometry_specs_are_distinct_and_defaulted() -> bool:
|
||||
return a and b and c and d and e and f and g
|
||||
|
||||
|
||||
func test_joke_shop_uses_the_real_sunset_strip_layout() -> bool:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root, "joke_shop")
|
||||
builder.build()
|
||||
var a := TestUtils.check(root.find_child("SignatureCanopy", true, false) != null,
|
||||
"the signature-covered canopy is built")
|
||||
var sign := root.find_child("ComedySignLabel", true, false) as Label3D
|
||||
var b := TestUtils.check(sign != null and sign.text.contains("JOKE")
|
||||
and sign.text.contains("SHOP"), "the circular blade sign carries the club wordmark")
|
||||
var c := TestUtils.check(root.get_node_or_null("SunsetHillside/DryHillside") != null,
|
||||
"the dry hillside rises behind the club")
|
||||
var d := TestUtils.check(root.get_node_or_null("SunsetNeighbours/WestMediterraneanBlock") != null
|
||||
and root.get_node_or_null("SunsetNeighbours/EastCommercialBlock") != null,
|
||||
"the west and east Sunset neighbours are built")
|
||||
var e := TestUtils.check(root.find_child("SunsetAcrossStreet", true, false) != null,
|
||||
"the opposite side of Sunset is built as background context")
|
||||
var f := TestUtils.check(root.find_child("EntranceStep", true, false) != null,
|
||||
"the low entrance step is built")
|
||||
var g := TestUtils.check(root.find_child("AlleyWall", true, false) == null,
|
||||
"the old alley walls are gone")
|
||||
var placements: Array = builder.spec.get("prop_placements", [])
|
||||
var h := TestUtils.check(not placements.is_empty()
|
||||
and WorldBuilder.placement_problems(placements).is_empty(),
|
||||
"the Joke Shop prop placements stay on the sidewalk and clear the lane")
|
||||
root.free()
|
||||
return a and b and c and d and e and f and g and h
|
||||
|
||||
func test_joke_shop_geometry_stays_inside_the_map_budget() -> bool:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root, "joke_shop")
|
||||
builder.build()
|
||||
var triangles := builder.world_triangle_count()
|
||||
var meshes := builder.world_mesh_count()
|
||||
print("joke shop map: %d triangles across %d meshes" % [triangles, meshes])
|
||||
var a := TestUtils.check(triangles < 150000,
|
||||
"Joke Shop triangle budget stays under 150k (got %d)" % triangles)
|
||||
var b := TestUtils.check(meshes < 700,
|
||||
"Joke Shop draw-call count stays under 700 meshes (got %d)" % meshes)
|
||||
root.free()
|
||||
return a and b
|
||||
|
||||
func test_hollywood_uses_the_real_landmark_layout() -> bool:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root)
|
||||
|
||||
Reference in new issue
Block a user