Replace Lucent city grid with street fields

This commit is contained in:
Meta Vens 2026-05-05 03:24:06 +01:00
commit 153f07adce
10 changed files with 186 additions and 60 deletions

View file

@ -5,6 +5,12 @@
Primary source: `Aetheria/Stories/Lucent Hostage Feed.md` and its interactive
Ghostlight scaffold. Supporting faction read:
`Aetheria/Worldbuilding/Pre-Elysium/Factions/Powers/Major/Lucent Media.md`.
Street-generation priors came from Parish and Muller's SIGGRAPH 2001
`Procedural Modeling of Cities` and Chen, Esch, Wonka, Muller, and Zhang's
SIGGRAPH 2008 `Interactive Procedural Street Modeling`:
- https://people.eecs.berkeley.edu/~sequin/CS285/PAPERS/Parish_Muller01.pdf
- https://peterwonka.net/Publications/pdfs/2008.SG.Chen.InteractiveProceduralStreetModeling.pdf
The story describes a Lucent tether station with a transfer lounge at the
media-eye end of the tether. The lounge has glass walls, an elevator gate, a
@ -27,6 +33,8 @@ therefore treats surfaces as active controls, not passive decoration.
- The media-eye lounge is at positive `X`.
- The sealed city bubble is at negative `X`, lower `Z`, and attached to the
tether by a load spine, elevator umbilical, collar, stays, and transfer node.
- The tether continues down through the dome to the city ground surface, landing
in a prestige anchor plaza.
- Crisis geometry lives inside the lounge: elevator gate and glass rail at the
threshold, safe-line arc behind it, security beyond the doors.
@ -102,14 +110,47 @@ add_panel("sponsor_risk_color_stack", (4.74, -0.86, 0.34), (0.15, 0.032, 0.62),
add_panel("audience_heat_meter", (3.55, -0.84, 0.30), (0.2, 0.032, 0.58), mats["heat"])
```
**The City Bubble Is A Miniature Pressure Field**
**Street Fields Beat Grids**
The sealed city uses deterministic noise for attention-lit tower variation.
This keeps the aquarium dense without hand-authoring every tower.
The first city pass used a regular grid. The revised pass uses a small
procedural street field instead: radial avenues grow from the tether anchor,
tangential promenade rings bend around it, and irregular annular parcels fill
between them. This is a compact use of two research lessons: global goals plus
local constraints from L-system city growth, and smoothly varying direction
fields from tensor-field street modeling.
```python
n = fbm_2d(ix * 0.27, iy * 0.33, seed=91)
append_box_parts(material_verts, material_faces, (x, y, CITY_BUBBLE_CENTER[2] - 0.30 + height * 0.5), axes, size)
for i in range(16):
base_angle = TAU * i / 16 + (hash01(i, 4, 11) - 0.5) * 0.12
line = []
for step in range(9):
u = step / 8
r = 0.12 + 1.42 * smoothstep(u)
angle = base_angle + 0.08 * pymath.sin(u * TAU + i)
line.append((center[0] + r * pymath.cos(angle), center[1] + r * pymath.sin(angle), ground_z + 0.025))
roads.append(line)
for ring_i, radius in enumerate([0.22, 0.42, 0.68, 0.95, 1.2, 1.42]):
for arc_i in range(3):
start = TAU * arc_i / 3 + ring_i * 0.21
end = start + TAU / 3 * (0.72 + 0.12 * hash01(ring_i, arc_i, 23))
roads.append(arc_points((center[0], center[1], ground_z + 0.028), radius, pymath.degrees(start), pymath.degrees(end), 24, plane="xy"))
```
**Land Use Falls Off From The Anchor**
The tether anchor plaza is the prestige attractor. Tallest skyscrapers cluster
around the plug-in point, the middle city steps down into irregular midrise
blocks and parks, and the outer ring fades into green faux-rural cottagecore.
This gives the skyline a social gradient instead of a height-map haircut.
```python
if zone < 0.28:
verts, faces = prestige_verts, prestige_faces
elif zone < 0.72:
verts, faces = tower_verts, tower_faces
else:
verts, faces = cottage_verts, cottage_faces
```
**Shader Graphs Are Geometry Evidence Too**
@ -136,15 +177,16 @@ Command:
Result:
```text
LUCENT_TETHER_VERIFY ok objects=72
LUCENT_TETHER_VERIFY ok objects=78
```
Render review rejected the first pass because the city bubble read as detached
from the tether and the EEVEE/default-material pass was too shallow. The
accepted revision uses Cycles, explicit bubble-to-tether attachment geometry,
and shader-node work. The verifier now checks the attachment objects, Cycles
engine, material shader-node types, named crisis geometry, render artifacts,
and the `VG Lucent Feed Ribbon` Geometry Script group.
shader-node work, and a non-grid city map. The verifier now checks the
attachment objects, Cycles engine, material shader-node types, named crisis
geometry, render artifacts, and the `VG Lucent Feed Ribbon` Geometry Script
group.
## Durable Lesson

View file

@ -153,6 +153,10 @@ def enrich_shader_graphs(mats):
add_shader_bump(mats["lucent_gray"], scale=45.0, detail=6.0, strength=0.045, distance=0.035)
add_shader_bump(mats["floor"], scale=24.0, detail=7.0, strength=0.035, distance=0.025)
add_shader_bump(mats["city"], scale=82.0, detail=4.0, strength=0.03, distance=0.02)
add_shader_bump(mats["prestige"], scale=64.0, detail=7.0, strength=0.025, distance=0.018)
add_shader_bump(mats["park"], scale=18.0, detail=6.0, strength=0.045, distance=0.028)
add_shader_bump(mats["cottage"], scale=31.0, detail=5.0, strength=0.055, distance=0.03)
add_shader_bump(mats["plaza"], scale=36.0, detail=6.0, strength=0.028, distance=0.02)
for key, pulse in [
("cyan", (0.65, 1.0, 1.0, 1.0)),
("amber", (1.0, 0.88, 0.32, 1.0)),
@ -224,6 +228,19 @@ def arc_points(center, radius, start_deg, end_deg, steps, plane="xy", wobble=0.0
return points
def annular_sector_points(center, inner_radius, outer_radius, start_angle, end_angle, z):
return [
(center[0] + inner_radius * pymath.cos(start_angle), center[1] + inner_radius * pymath.sin(start_angle), z),
(center[0] + outer_radius * pymath.cos(start_angle), center[1] + outer_radius * pymath.sin(start_angle), z),
(center[0] + outer_radius * pymath.cos(end_angle), center[1] + outer_radius * pymath.sin(end_angle), z),
(center[0] + inner_radius * pymath.cos(end_angle), center[1] + inner_radius * pymath.sin(end_angle), z),
]
def add_flat_polygon(name, verts, material):
return add_mesh_parts(name, verts, [(0, 1, 2, 3)], material)
def add_floor_patch(name, center, width, depth, material, z=0.0):
return add_box(name, (center[0], center[1], z), ((1, 0, 0), (0, 1, 0), (0, 0, 1)), (width, depth, 0.035), material)
@ -273,45 +290,111 @@ def add_city_bubble(mats):
segments=96,
)
city_verts, city_faces = [], []
light_verts, light_faces = [], []
ground_z = CITY_BUBBLE_CENTER[2] - 0.30
center = (CITY_BUBBLE_CENTER[0], CITY_BUBBLE_CENTER[1])
tower_verts, tower_faces = [], []
prestige_verts, prestige_faces = [], []
cottage_verts, cottage_faces = [], []
park_faces = []
plaza_faces = []
roads = []
for ix in range(28):
x = CITY_BUBBLE_CENTER[0] - 1.2 + ix * 0.09
for iy in range(22):
y = -1.15 + iy * 0.11
ell = ((x - CITY_BUBBLE_CENTER[0]) / 1.42) ** 2 + (y / 1.42) ** 2
if ell > 1.0:
# Street field: major avenues radiate from the tether anchor, then bend
# toward a tangential promenade field. This borrows the tensor-field idea
# without pretending this tiny bubble needs a whole GIS stack.
for i in range(16):
base_angle = TAU * i / 16 + (hash01(i, 4, 11) - 0.5) * 0.12
line = []
for step in range(9):
u = step / 8
r = 0.12 + 1.42 * smoothstep(u)
drift = 0.22 * pymath.sin(u * pymath.pi) * (hash01(i, step, 17) - 0.5)
angle = base_angle + drift + 0.08 * pymath.sin(u * TAU + i)
line.append((center[0] + r * pymath.cos(angle), center[1] + r * pymath.sin(angle), ground_z + 0.025))
roads.append(line)
for ring_i, radius in enumerate([0.22, 0.42, 0.68, 0.95, 1.2, 1.42]):
for arc_i in range(3):
start = TAU * arc_i / 3 + ring_i * 0.21
end = start + TAU / 3 * (0.72 + 0.12 * hash01(ring_i, arc_i, 23))
roads.append(arc_points((center[0], center[1], ground_z + 0.028), radius, pymath.degrees(start), pymath.degrees(end), 24, plane="xy", wobble=0.018))
# Anchor plaza: the tether physically lands on the ground surface. The
# skyline knows where power plugs in.
for i in range(8):
a0 = TAU * i / 8
a1 = TAU * (i + 1) / 8
plaza_faces.extend(annular_sector_points(center, 0.0, 0.23, a0, a1, ground_z + 0.006))
add_flat_polygon("city_bubble_tether_anchor_plaza_core", annular_sector_points(center, 0.0, 0.24, 0.0, TAU / 4, ground_z + 0.012), mats["plaza"])
add_torus("city_bubble_anchor_plaza_ring", (center[0], center[1], ground_z + 0.025), 0.32, 0.011, mats["soft_white"], segments=96)
rings = [0.24, 0.42, 0.62, 0.84, 1.08, 1.31, 1.52]
for ring in range(len(rings) - 1):
inner = rings[ring]
outer = rings[ring + 1]
zone = ring / (len(rings) - 2)
cells = int(18 + ring * 7)
for cell in range(cells):
u0 = cell / cells
u1 = (cell + 0.78 + 0.34 * hash01(ring, cell, 33)) / cells
a0 = TAU * u0 + 0.1 * pymath.sin(ring * 1.7)
a1 = TAU * u1 + 0.07 * (hash01(cell, ring, 35) - 0.5)
n = fbm_2d(ring * 0.61, cell * 0.29, seed=91)
park_bias = fbm_2d(pymath.cos((a0 + a1) * 0.5) * 2.2 + ring, pymath.sin((a0 + a1) * 0.5) * 2.2, seed=121)
if zone > 0.32 and park_bias > 0.68:
park_faces.extend(annular_sector_points(center, inner + 0.025, outer - 0.02, a0 + 0.025, a1 - 0.018, ground_z + 0.01))
continue
n = fbm_2d(ix * 0.27, iy * 0.33, seed=91)
if n < 0.33:
continue
height = 0.06 + 0.28 * n
material_verts, material_faces = (light_verts, light_faces) if n > 0.72 else (city_verts, city_faces)
append_box_parts(
material_verts,
material_faces,
(x, y, CITY_BUBBLE_CENTER[2] - 0.30 + height * 0.5),
((1, 0, 0), (0, 1, 0), (0, 0, 1)),
(0.045 + 0.03 * n, 0.055 + 0.025 * hash01(ix, iy, 7), height),
)
if ix % 4 == 0:
roads.append([(x, -1.25, CITY_BUBBLE_CENTER[2] - 0.21), (x + 0.15 * pymath.sin(ix), 0.0, CITY_BUBBLE_CENTER[2] - 0.19), (x, 1.25, CITY_BUBBLE_CENTER[2] - 0.21)])
for iy in range(-10, 11, 3):
y = iy * 0.11
roads.append([(CITY_BUBBLE_CENTER[0] - 1.15, y, CITY_BUBBLE_CENTER[2] - 0.22), (CITY_BUBBLE_CENTER[0], y + 0.08 * pymath.sin(iy), CITY_BUBBLE_CENTER[2] - 0.20), (CITY_BUBBLE_CENTER[0] + 1.15, y, CITY_BUBBLE_CENTER[2] - 0.22)])
add_mesh_parts("city_bubble_miniature_skyscraper_mesh", city_verts, city_faces, mats["city"])
add_mesh_parts("city_bubble_attention_lit_tower_mesh", light_verts, light_faces, mats["cyan"])
add_multi_polyline_curve("city_bubble_aquarium_street_grid", roads, 0.006, mats["soft_white"], resolution=2)
r = inner + (outer - inner) * (0.45 + 0.22 * (n - 0.5))
angle = (a0 + a1) * 0.5
radial_axis = (pymath.cos(angle), pymath.sin(angle), 0.0)
tangent_axis = (-pymath.sin(angle), pymath.cos(angle), 0.0)
radial_width = max(0.04, (outer - inner) * (0.36 + 0.28 * n))
tangential_width = max(0.045, r * (a1 - a0) * (0.55 + 0.3 * hash01(cell, ring, 37)))
if zone < 0.28:
height = 0.5 + 0.62 * n
verts, faces = prestige_verts, prestige_faces
size = (tangential_width * 0.72, radial_width * 0.8, height)
loc = (center[0] + r * radial_axis[0], center[1] + r * radial_axis[1], ground_z + height * 0.5)
elif zone < 0.72:
height = 0.16 + 0.36 * n * (1.0 - zone * 0.35)
verts, faces = tower_verts, tower_faces
size = (tangential_width * 0.82, radial_width * 0.9, height)
loc = (center[0] + r * radial_axis[0], center[1] + r * radial_axis[1], ground_z + height * 0.5)
else:
if n < 0.38:
park_faces.extend(annular_sector_points(center, inner + 0.02, outer - 0.02, a0 + 0.02, a1 - 0.02, ground_z + 0.012))
continue
height = 0.045 + 0.07 * n
verts, faces = cottage_verts, cottage_faces
size = (tangential_width * 0.55, radial_width * 0.6, height)
loc = (center[0] + r * radial_axis[0], center[1] + r * radial_axis[1], ground_z + height * 0.5)
append_box_parts(verts, faces, loc, (tangent_axis, radial_axis, (0, 0, 1)), size)
if park_faces:
verts = park_faces
faces = [(i, i + 1, i + 2, i + 3) for i in range(0, len(verts), 4)]
add_mesh_parts("city_bubble_interspersed_park_cells", verts, faces, mats["park"])
add_mesh_parts("city_bubble_prestige_anchor_skyscrapers", prestige_verts, prestige_faces, mats["prestige"])
add_mesh_parts("city_bubble_midcity_irregular_blocks", tower_verts, tower_faces, mats["city"])
add_mesh_parts("city_bubble_faux_rural_cottagecore_edge", cottage_verts, cottage_faces, mats["cottage"])
add_multi_polyline_curve("city_bubble_tensor_field_street_network", roads, 0.006, mats["soft_white"], resolution=3)
add_multi_polyline_curve(
"city_bubble_prestige_plaza_spokes",
[[(center[0], center[1], ground_z + 0.04), road[-1]] for road in roads[:16:2]],
0.012,
mats["cyan"],
resolution=3,
)
def add_city_bubble_tether_attachment(mats):
x, y, z = CITY_TETHER_JUNCTION
top = (x, y, z)
collar = (CITY_BUBBLE_CENTER[0], CITY_BUBBLE_CENTER[1], CITY_BUBBLE_CENTER[2] + 1.02)
plaza = (CITY_BUBBLE_CENTER[0], CITY_BUBBLE_CENTER[1], CITY_BUBBLE_CENTER[2] - 0.30)
keel = (CITY_BUBBLE_CENTER[0], CITY_BUBBLE_CENTER[1], CITY_BUBBLE_CENTER[2] - 0.22)
add_cylinder_between("city_bubble_tether_load_spine", top, collar, 0.045, mats["tether"], vertices=16)
add_cylinder_between("city_bubble_tether_load_spine", top, plaza, 0.045, mats["tether"], vertices=16)
add_cylinder_between("city_bubble_elevator_umbilical", (x + 0.14, 0.0, -0.05), (collar[0] + 0.14, 0.0, collar[2] - 0.03), 0.022, mats["cyan"], vertices=10)
add_cylinder_between("city_bubble_elevator_drop_to_anchor_plaza", (x + 0.14, 0.0, collar[2] - 0.03), (plaza[0] + 0.14, 0.0, plaza[2] + 0.06), 0.018, mats["cyan"], vertices=10)
add_torus(
"city_bubble_upper_tether_collar",
collar,
@ -453,6 +536,10 @@ def build_scene():
"private": mat("Mara private rail green", (0.32, 1.0, 0.62), emission=True, strength=0.38),
"aquarium": mat("aquarium blue", (0.02, 0.28, 0.55), alpha=0.58),
"city": mat("sealed miniature city", (0.58, 0.62, 0.66), alpha=0.95),
"prestige": mat("prestige anchor skyscraper glass", (0.72, 0.82, 0.9), emission=True, strength=0.08, alpha=0.95),
"park": mat("interspersed park green", (0.12, 0.48, 0.22), alpha=0.92),
"cottage": mat("verdant faux rural cottagecore", (0.46, 0.64, 0.39), alpha=0.96),
"plaza": mat("tether anchor plaza stone", (0.68, 0.7, 0.66), alpha=0.96),
"label": mat("label white", (0.92, 0.95, 1.0), emission=True, strength=0.45),
}
enrich_shader_graphs(mats)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,000 KiB

After

Width:  |  Height:  |  Size: 1,010 KiB

Before After
Before After

View file

@ -29,21 +29,10 @@ builder library and artifact schemas do not.
Corpus inventory, graph maps, verification notes, and doctrine live in
`docs/research/`. This handoff is not the ledger.
Accepted corpus families so far:
- Local math/display/utility graphs from Shriinivas samples: Cartesian helper
and function graphs, pie chart, field-value digit display, parametric/polar
equations.
- Quellenform `CurveToMeshUV` utility sample.
- Official Blender demo tranche: instance attributes, index-of-nearest,
shortest-path labyrinth, and raycast minigame helpers.
- IRCSS French Houses footholds: `MakeSpiral -> VG Make Spiral` and
`PointyGothicCone -> VG Pointy Gothic Cone`, verified against source
evaluated geometry with max delta `0.0`.
Current IRCSS frontier: `MakeSpiral` and `PointyGothicCone` are accepted
footholds. Blockers are repeat-zone feedback, repeat `Top` outputs, foreach
zones, gizmo nodes, and rejected empty-output `WindowBeams` harness. IRCSS maps
Accepted corpus families include local Shriinivas samples, Quellenform
`CurveToMeshUV`, official Blender demos, and IRCSS French Houses footholds.
IRCSS blockers remain repeat-zone feedback, repeat `Top` outputs, foreach
zones, gizmo nodes, and the rejected empty-output `WindowBeams` harness. Maps
live in `docs/research/translations/ircss-french-houses-*.md`.
From-scratch story-bound builds:
@ -56,10 +45,10 @@ From-scratch story-bound builds:
verifier: `tools/verify_aetheria_bloom_habitat.py`.
- `examples/geometry_script/lucent_tether_habitat.py` generates the Lucent
tether habitat from Ghostlight `Lucent Hostage Feed`: tether axis, city bubble
below, media-eye lounge, elevator threshold, glass rail, white safe-line,
overlays, control rail, side panels, risk/heat surfaces, and security doors.
Accepted revision uses Cycles, shader-node work, and explicit city-bubble
attachment to the tether.
below, media-eye lounge, crisis threshold, overlays, control/side panels, and
security doors. Accepted revision uses Cycles, shader nodes, explicit bubble
attachment, radial/tangential streets, irregular parcels, prestige anchor
towers, parks, and faux-rural edge falloff.
Build notes: `docs/research/builds/lucent-tether-habitat.md`; verifier:
`tools/verify_lucent_tether_habitat.py`.

View file

@ -44,3 +44,4 @@
{"ts": "2026-05-05T01:25:43+00:00", "type": "implementation", "status": "accepted", "note": "Created the first reusable vibegeometry Python helper library for coordinate frames, deterministic fields, dense mesh batching, Blender scene primitives, and verifier helpers; refactored the Bloom build and verifier to use it, then rebuilt and verified the scene in Blender with 1028 geometry/text objects."}
{"ts": "2026-05-05T01:40:49+00:00", "type": "implementation", "status": "accepted", "note": "Built and verified the Lucent tether habitat from Ghostlight source: tether axis, city bubble below, media-eye transfer lounge, glass rail/safe-line threshold, Lucent overlay/control surfaces, and an inspectable VG Lucent Feed Ribbon Geometry Script group. Render review accepted overview, lounge, and city-bubble inspection artifacts."}
{"ts": "2026-05-05T01:59:41+00:00", "type": "implementation", "status": "accepted", "note": "Revised Lucent tether habitat after visual review: city bubble now has explicit tether load spine, elevator umbilical, collar, stays, and transfer node; renders now use Cycles; shader graphs add procedural noise/bump/ramp nodes to glass, tether, and Lucent overlay surfaces; verifier checks these contracts."}
{"ts": "2026-05-05T02:20:23+00:00", "type": "implementation", "status": "accepted", "note": "Replaced Lucent city-bubble grid with street-generation-inspired radial/tangential field roads, irregular annular parcel cells, anchor-plaza prestige skyscrapers, park voids, midcity blocks, and faux-rural cottagecore edge falloff; tether now visibly descends to the city ground-surface plaza."}

View file

@ -101,7 +101,7 @@ data_flow:
- If state grows faster than understanding, cut it back.
current_status:
summary: VibeGeometry has verified Geometry Script translations for local samples, official Blender demos, and IRCSS French Houses footholds, plus from-scratch Aetheria Bloom and Lucent tether habitat builds. Durable lessons now driving the pipeline: Python orchestrates intent and batching; Geometry Script emits inspectable node groups; source-bound scenes need explicit coordinate contracts before ornament; large habitat parts need visible load paths across coordinate frames; organic occupancy needs deterministic noise fields; dense detail must be batched; institutional spaces should model power as surfaces, rails, overlays, thresholds, shader behavior, and camera evidence; and visual acceptance needs domain-facing inspection renders plus verifier checks, not only overview renders. The first reusable `vibegeometry/` helper library now carries coordinate frames, fields, batching, Blender scene primitives, and verifier helpers used by the Bloom and Lucent builds. Known graph-tooling blockers remain repeat-zone feedback, repeat Top outputs, foreach zones, and gizmo nodes.
summary: VibeGeometry has verified Geometry Script translations for local samples, official Blender demos, and IRCSS French Houses footholds, plus from-scratch Aetheria Bloom and Lucent tether habitat builds. Durable lessons now driving the pipeline: Python orchestrates intent and batching; Geometry Script emits inspectable node groups; source-bound scenes need explicit coordinate contracts before ornament; large habitat parts need visible load paths across coordinate frames; organic city maps need street fields, irregular parcels, parks, and land-use gradients rather than grids; dense detail must be batched; institutional spaces should model power as surfaces, rails, overlays, thresholds, shader behavior, and camera evidence; and visual acceptance needs domain-facing inspection renders plus verifier checks, not only overview renders. The first reusable `vibegeometry/` helper library now carries coordinate frames, fields, batching, Blender scene primitives, and verifier helpers used by the Bloom and Lucent builds. Known graph-tooling blockers remain repeat-zone feedback, repeat Top outputs, foreach zones, and gizmo nodes.
next_action: Extract the first higher-level reusable builder seam from the completed story-bound builds: either threshold/control-rail interface kits from the Lucent habitat or endcap terrace/spiral artery kits from the Bloom, then bind that seam to scene-brief, manifest, inspection-render, and verifier contract drafts.
remotes:
vibegeometry: https://github.com/GameCult/VibeGeometry

View file

@ -24,9 +24,16 @@ REQUIRED_OBJECTS = [
"city_bubble_elevator_umbilical",
"city_bubble_upper_tether_collar",
"city_bubble_tether_transfer_node",
"city_bubble_elevator_drop_to_anchor_plaza",
"city_bubble_under_keel_counterweight",
"city_bubble_miniature_skyscraper_mesh",
"city_bubble_attention_lit_tower_mesh",
"city_bubble_tether_anchor_plaza_core",
"city_bubble_anchor_plaza_ring",
"city_bubble_interspersed_park_cells",
"city_bubble_prestige_anchor_skyscrapers",
"city_bubble_midcity_irregular_blocks",
"city_bubble_faux_rural_cottagecore_edge",
"city_bubble_tensor_field_street_network",
"city_bubble_prestige_plaza_spokes",
"media_eye_transfer_lounge_glass_shell",
"media_eye_public_camera_eye",
"transfer_lounge_curved_floor_slab",