forked from woofmeow/straywild
Expand generated terrain with biome-driven props
This commit is contained in:
parent
e8888ed05a
commit
1e24fb0bfc
103 changed files with 5427 additions and 351 deletions
135
tests/terrain_biome_validation.gd
Normal file
135
tests/terrain_biome_validation.gd
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
extends SceneTree
|
||||
|
||||
const BIOME_CATALOG: TerrainBiomeCatalog = preload(
|
||||
"res://world/generation/biomes/terrain_biome_catalog.tres"
|
||||
)
|
||||
const PROP_CATALOG: TerrainPropCatalog = preload(
|
||||
"res://world/generation/props/terrain_prop_catalog.tres"
|
||||
)
|
||||
const EXPECTED_BIOMES: Array[StringName] = [
|
||||
&"biome_plains",
|
||||
&"biome_forest",
|
||||
&"biome_pine_forest",
|
||||
&"biome_coast",
|
||||
]
|
||||
const TEST_SEED := 13001
|
||||
|
||||
var _failures: Array[String] = []
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred(&"_run")
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
_validate_catalog()
|
||||
_validate_assignment()
|
||||
_finish()
|
||||
|
||||
|
||||
func _validate_catalog() -> void:
|
||||
for error: String in BIOME_CATALOG.validation_errors():
|
||||
_check(false, error)
|
||||
_check(
|
||||
BIOME_CATALOG.definitions.size() == EXPECTED_BIOMES.size(),
|
||||
"The biome catalog must contain all initial authored profiles.",
|
||||
)
|
||||
for biome_id: StringName in EXPECTED_BIOMES:
|
||||
var biome := BIOME_CATALOG.definition_for_id(biome_id)
|
||||
_check(biome != null, "The biome catalog is missing %s." % biome_id)
|
||||
if biome == null:
|
||||
continue
|
||||
for rule: TerrainBiomePropRule in biome.prop_rules:
|
||||
for prop_id_value: String in rule.allowed_prop_ids:
|
||||
var prop := PROP_CATALOG.definition_for_id(
|
||||
StringName(prop_id_value)
|
||||
)
|
||||
_check(
|
||||
prop != null and rule.allows_prop(prop),
|
||||
"%s has an invalid %s prop rule."
|
||||
% [biome_id, prop_id_value],
|
||||
)
|
||||
|
||||
|
||||
func _validate_assignment() -> void:
|
||||
var records := _synthetic_records()
|
||||
var first := TerrainBiomeAssigner.assign(
|
||||
BIOME_CATALOG,
|
||||
records,
|
||||
TEST_SEED,
|
||||
)
|
||||
var second := TerrainBiomeAssigner.assign(
|
||||
BIOME_CATALOG,
|
||||
records,
|
||||
TEST_SEED,
|
||||
)
|
||||
_check(first == second, "Biome assignment must be deterministic by seed.")
|
||||
_check(
|
||||
TerrainBiomeAssigner.fingerprint(first).length() == 64,
|
||||
"Biome assignments must expose a SHA-256 fingerprint.",
|
||||
)
|
||||
var counts := TerrainBiomeAssigner.counts(first)
|
||||
for biome_id: StringName in EXPECTED_BIOMES:
|
||||
_check(
|
||||
counts.get(biome_id, 0) > 0,
|
||||
"The synthetic map must contain %s." % biome_id,
|
||||
)
|
||||
_check(
|
||||
first.get(Vector2i(3, 3), &"") == &"biome_plains",
|
||||
"The spawn-tagged center must remain plains.",
|
||||
)
|
||||
for record: Dictionary in records:
|
||||
var coordinate: Vector2i = record["coordinate"]
|
||||
var tags: PackedStringArray = record["tags"]
|
||||
var biome_id: StringName = first.get(coordinate, &"")
|
||||
if "fresh_water" in tags:
|
||||
_check(
|
||||
biome_id == &"",
|
||||
"Freshwater-only chunks must not inherit a land-prop biome.",
|
||||
)
|
||||
continue
|
||||
var biome := BIOME_CATALOG.definition_for_id(biome_id)
|
||||
_check(
|
||||
biome != null and biome.supports_chunk_tags(tags),
|
||||
"Biome %s does not support chunk %s."
|
||||
% [biome_id, coordinate],
|
||||
)
|
||||
|
||||
|
||||
func _synthetic_records() -> Array[Dictionary]:
|
||||
var result: Array[Dictionary] = []
|
||||
for row: int in 7:
|
||||
for column: int in 7:
|
||||
var coordinate := Vector2i(column, row)
|
||||
var tags := PackedStringArray(["land", "walkable", "grass"])
|
||||
if row == 0:
|
||||
tags = PackedStringArray(["land", "walkable", "sand"])
|
||||
elif coordinate == Vector2i(0, 6):
|
||||
tags = PackedStringArray([
|
||||
"land",
|
||||
"walkable",
|
||||
"fresh_water",
|
||||
"pond",
|
||||
])
|
||||
elif coordinate == Vector2i(3, 3):
|
||||
tags.append("spawn")
|
||||
result.append({
|
||||
"coordinate": coordinate,
|
||||
"tags": tags,
|
||||
})
|
||||
return result
|
||||
|
||||
|
||||
func _check(condition: bool, message: String) -> void:
|
||||
if not condition:
|
||||
_failures.append(message)
|
||||
|
||||
|
||||
func _finish() -> void:
|
||||
if _failures.is_empty():
|
||||
print("Terrain biome validation: PASS")
|
||||
quit(0)
|
||||
return
|
||||
for failure: String in _failures:
|
||||
printerr("Terrain biome validation: ", failure)
|
||||
quit(1)
|
||||
Loading…
Add table
Add a link
Reference in a new issue