Files
Ransom-s-wake/tools/sites/terrain_showcase_recipe.gd
T
OlivierandClaude Fable 5.1 61ef4a892d feat(tools): irregular strata and angular boulder blocks
Strata gain a dip, a slow seeded warp that bends and notches the beds, and
a per-bed thickness and hardness jitter with ordered boundaries, so walls
never invert. BoulderField gains an angularity parameter: elongated
super-ellipse slabs with flat tops, sharp shoulders, random heading and
tilt, footprint area preserved. Both sites are re-baked with the new
settings; the coral heads stay rounded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 23:31:11 +02:00

126 lines
6.1 KiB
GDScript

extends RefCounted
## Catalogue site « Jardin des Formes »: one quarter per reference landform
## (docs/briefs/terrain-varied-landforms.md §5). No wreck, no route; a single
## mooring beacon at the centre. Field 512 x 512 m at 1 m, +X east, +Z south.
const SiteTerrainBaker = preload("res://tools/site_terrain_baker.gd")
const SonarMaterial = preload("res://game/domain/sonar/sonar_material.gd")
const SiteTerrainData = preload("res://game/domain/sites/site_terrain_data.gd")
const DiveSiteDefinition = preload("res://game/domain/sites/dive_site_definition.gd")
const SitePlacement = preload("res://game/domain/sites/site_placement.gd")
# North-west: stratified canyon cut through a mesa.
const MESA_CENTRE := Vector2(-120.0, -130.0)
const CANYON_PATH: Array[Vector2] = [
Vector2(-205.0, -85.0), Vector2(-150.0, -120.0), Vector2(-110.0, -150.0), Vector2(-60.0, -200.0),
]
const CANYON_HALF_WIDTH_M := 14.0
const CANYON_DEPTH_M := 20.0
# North-east: crevasse between two buttes.
const WEST_BUTTE_CENTRE := Vector2(80.0, -120.0)
const EAST_BUTTE_CENTRE := Vector2(165.0, -125.0)
const CREVASSE_PATH: Array[Vector2] = [
Vector2(122.0, -200.0), Vector2(118.0, -160.0), Vector2(124.0, -120.0), Vector2(119.0, -80.0), Vector2(123.0, -40.0),
]
const CREVASSE_HALF_WIDTH_M := 3.0
const CREVASSE_DEPTH_M := 20.0
# South-west: boulder field on rippled sand.
const BOULDER_FIELD_CENTRE := Vector2(-120.0, 110.0)
const BOULDER_FIELD_RADIUS_M := 75.0
# South-east: two rock spurs framing a sand channel.
const WEST_SPUR_CENTRE := Vector2(80.0, 120.0)
const EAST_SPUR_CENTRE := Vector2(170.0, 125.0)
const CHANNEL_CENTRE := Vector2(125.0, 120.0)
# South: sinuous escarpment with rounded knolls on the slope below.
const ESCARPMENT_PATH: Array[Vector2] = [
Vector2(-270.0, 215.0), Vector2(-150.0, 205.0), Vector2(-40.0, 225.0), Vector2(60.0, 205.0),
Vector2(170.0, 228.0), Vector2(270.0, 210.0),
]
const ESCARPMENT_DROP_M := 22.0
static func recipe() -> SiteTerrainBaker.Recipe:
var result := SiteTerrainBaker.Recipe.new()
result.columns = 513
result.rows = 513
result.cell_size_m = 1.0
result.origin_x_m = -256.0
result.origin_z_m = -256.0
result.floor_elevation_m = -80.0
result.rock_slope_degrees = 20.0
result.rock_reflectivity = 0.72
result.sand_reflectivity = 0.45
result.primitives = [
# Base plateau: 30 m deep at the centre, 4 m deeper over the 500 m southward.
SiteTerrainBaker.SlopedPlane.new(30.0, 0.0, -0.008, 0.0, 0.0),
# NW — la Mesa fendue: flat rock plateau 6 m high, 20 m deep canyon with a
# 14 m wide flat floor, 55 degree walls cut into 4 m ledges by the Strata
# modifier (one ledge every 2.8 m across, resolvable at 1 m per cell), rippled
# sand on the floor.
SiteTerrainBaker.Outcrop.new(MESA_CENTRE, 95.0, 85.0, 6.0, 10.0, 101, 6.0, true),
SiteTerrainBaker.Canyon.new(PackedVector2Array(CANYON_PATH), CANYON_HALF_WIDTH_M, CANYON_DEPTH_M, 7.0, 102, 2.0, SonarMaterial.Value.SAND),
SiteTerrainBaker.Ripples.new(Vector2(0.8, -0.6), 4.0, 0.25, Vector2(-130.0, -140.0), 70.0),
# NE — la Fente: two buttes 8-9 m high with a 6 m wide, 20 m deep slot between them.
SiteTerrainBaker.Outcrop.new(WEST_BUTTE_CENTRE, 38.0, 70.0, 8.0, 8.0, 201, 5.0, true),
SiteTerrainBaker.Outcrop.new(EAST_BUTTE_CENTRE, 38.0, 75.0, 9.0, 8.0, 202, 5.0, true),
SiteTerrainBaker.Canyon.new(PackedVector2Array(CREVASSE_PATH), CREVASSE_HALF_WIDTH_M, CREVASSE_DEPTH_M, 1.0, 203, 1.0, SonarMaterial.Value.SAND),
# SW — le Chaos: ninety angular blocks of 2-6 m radius plus six rounded coral heads,
# on rippled sand.
SiteTerrainBaker.BoulderField.new(BOULDER_FIELD_CENTRE, BOULDER_FIELD_RADIUS_M, 301, 90, 2.0, 6.0, 0.7, 0.85),
SiteTerrainBaker.BoulderField.new(Vector2(-100.0, 130.0), 40.0, 302, 6, 6.0, 9.0, 0.6, 0.0),
SiteTerrainBaker.Ripples.new(Vector2(1.0, 0.3), 3.5, 0.3, BOULDER_FIELD_CENTRE, 110.0),
# SE — les Éperons: two pitted rock spurs 7-8 m high framing a 20 m sand channel
# littered with small blocks.
SiteTerrainBaker.Outcrop.new(WEST_SPUR_CENTRE, 30.0, 60.0, 8.0, 5.0, 401, 7.0, true),
SiteTerrainBaker.Outcrop.new(EAST_SPUR_CENTRE, 30.0, 55.0, 7.0, 5.0, 402, 7.0, true),
SiteTerrainBaker.BoulderField.new(CHANNEL_CENTRE, 50.0, 403, 12, 1.5, 3.0, 0.8, 1.0),
# S — la Corniche: sinuous 22 m escarpment, then a 42 degree slope to the 80 m floor,
# with rounded knolls on the slope.
SiteTerrainBaker.Escarpment.new(PackedVector2Array(ESCARPMENT_PATH), ESCARPMENT_DROP_M, 6.0, 0.9, 501, 8.0),
SiteTerrainBaker.Outcrop.new(Vector2(-60.0, 240.0), 12.0, 10.0, 5.0, 10.0, 502, 2.0, true),
SiteTerrainBaker.Outcrop.new(Vector2(40.0, 236.0), 10.0, 9.0, 4.0, 9.0, 503, 2.0, true),
SiteTerrainBaker.Outcrop.new(Vector2(130.0, 245.0), 14.0, 11.0, 6.0, 11.0, 504, 2.0, true),
# Roughness: hummocks and swales from 250 m down to 15 m, the 50 m texture,
# and cell-scale pitting.
SiteTerrainBaker.Roughness.new(2026, 0.004, 2.2, 5),
SiteTerrainBaker.Roughness.new(2029, 0.012, 1.2, 4),
SiteTerrainBaker.Roughness.new(2030, 0.05, 0.6, 3),
SiteTerrainBaker.Roughness.new(1933, 0.02, 0.6),
SiteTerrainBaker.Roughness.new(2027, 0.15, 0.2),
]
result.modifiers = [
# Crumbly rock faces, smooth sand. Before the strata so the ledges stay flat.
SiteTerrainBaker.SlopeRoughness.new(2028, 0.12, 0.7, 20.0, 40.0),
# Strata on the north-west quarter only (mesa flanks and canyon walls): beds of
# about 4 m, dipping 1.3 degrees to the south-east, bent by 2.4 m of slow warp,
# each bed with its own thickness and hardness.
SiteTerrainBaker.Strata.new(
4.0, 0.85, 30.0, 50.0, Rect2(-256.0, -256.0, 256.0, 256.0),
Vector2(0.015, 0.018), 105, 2.4, 0.5
),
]
return result
static func definition(terrain: SiteTerrainData) -> DiveSiteDefinition:
var result := DiveSiteDefinition.new()
result.site_id = &"terrain_showcase"
result.display_name = "Jardin des Formes"
result.terrain = terrain
result.playable_bounds_m = Rect2(-220.0, -220.0, 440.0, 440.0)
result.spawn_position_m = Vector3(0.0, -12.0, 0.0)
result.spawn_yaw_radians = 0.0
var anchor := SitePlacement.new()
anchor.placement_id = &"vessel_anchor"
anchor.kind = SitePlacement.Kind.VESSEL_ANCHOR
anchor.position_m = Vector3(0.0, -16.0, 0.0)
result.placements = [anchor]
return result