Files
Ransom-s-wake/tools/bake_site_terrain.gd
OlivierandClaude Fable 5.1 f7e60315b1 feat(content): bake the Jardin des Formes terrain showcase site
Five reference landforms on one 512 m field at 1 m per cell: a stratified
canyon through a mesa, a crevasse between two buttes, a boulder field on
rippled sand, two rock spurs framing a sand channel, and a sinuous
escarpment with knolls on the slope below.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 21:45:09 +02:00

75 lines
2.8 KiB
GDScript

extends SceneTree
const SiteTerrainBaker = preload("res://tools/site_terrain_baker.gd")
const RECIPES := {
"vehicle_test": "res://tools/sites/vehicle_test_terrain_recipe.gd",
"zone1_vigilant": "res://tools/sites/zone1_vigilant_recipe.gd",
"terrain_showcase": "res://tools/sites/terrain_showcase_recipe.gd",
}
const OUTPUT_DIRECTORY := "res://content/sites"
const PREVIEW_DIRECTORY := "res://docs/briefs/captures"
func _init() -> void:
var arguments := OS.get_cmdline_user_args()
if arguments.is_empty() or not RECIPES.has(arguments[0]):
push_error("usage: -- <%s>" % " | ".join(RECIPES.keys()))
quit(1)
return
var name: String = arguments[0]
var recipe_script := load(RECIPES[name]) as GDScript
if recipe_script == null:
push_error("recipe script %s is missing" % RECIPES[name])
quit(1)
return
var recipe: SiteTerrainBaker.Recipe = recipe_script.recipe()
var data := SiteTerrainBaker.bake(recipe)
if data == null:
push_error("recipe %s did not bake valid terrain" % name)
quit(1)
return
DirAccess.make_dir_recursive_absolute(OUTPUT_DIRECTORY)
DirAccess.make_dir_recursive_absolute(PREVIEW_DIRECTORY)
var output_path := "%s/%s_terrain.res" % [OUTPUT_DIRECTORY, name]
var save_error := ResourceSaver.save(data, output_path, ResourceSaver.FLAG_CHANGE_PATH)
if save_error != OK:
push_error("cannot save %s (%d)" % [output_path, save_error])
quit(1)
return
# ResourceSaver restores the previous path after saving, so the data must
# take over the baked path explicitly for the definition to reference it.
data.take_over_path(output_path)
var preview_path := "%s/%s_terrain_preview.png" % [PREVIEW_DIRECTORY, name]
var preview_error := SiteTerrainBaker.write_preview_png(data, preview_path)
if preview_error != OK:
push_error("cannot write %s (%d)" % [preview_path, preview_error])
quit(1)
return
var definition = recipe_script.definition(data)
var definition_error: String = definition.validation_error()
if not definition_error.is_empty():
push_error("recipe %s definition is invalid: %s" % [name, definition_error])
quit(1)
return
var definition_path := "%s/%s.tres" % [OUTPUT_DIRECTORY, name]
var definition_save_error := ResourceSaver.save(definition, definition_path)
if definition_save_error != OK:
push_error("cannot save %s (%d)" % [definition_path, definition_save_error])
quit(1)
return
var rock_cells := 0
for material: int in data.materials:
if material == SiteTerrainBaker.SonarMaterial.Value.ROCK:
rock_cells += 1
var minimum := data.elevations_m[0]
var maximum := data.elevations_m[0]
for elevation: float in data.elevations_m:
minimum = minf(minimum, elevation)
maximum = maxf(maximum, elevation)
print("Baked %s: %d x %d cells, elevation %.1f .. %.1f m, rock %.0f %%" % [
name, data.columns, data.rows, minimum, maximum,
100.0 * float(rock_cells) / float(data.materials.size())
])
quit(0)