Add deterministic generated worlds

This commit is contained in:
Alexander Sellite 2026-08-19 17:32:40 -04:00
parent 19f63bd656
commit e8888ed05a
87 changed files with 3743 additions and 139 deletions

View file

@ -0,0 +1,81 @@
extends SceneTree
const CATALOG: TerrainChunkCatalog = preload(
"res://world/generation/chunks/terrain_chunk_catalog.tres"
)
const MATCH_TOLERANCE := 0.01
func _initialize() -> void:
call_deferred(&"_run")
func _run() -> void:
var variants: Array[TerrainChunkVariant] = []
for definition: TerrainChunkDefinition in CATALOG.definitions:
var seen: Dictionary[String, bool] = {}
for variant: TerrainChunkVariant in TerrainChunkAnalyzer.create_variants(
definition,
CATALOG.chunk_size,
):
var signature := variant.topology_signature(0.001)
if seen.has(signature):
continue
seen[signature] = true
variants.append(variant)
print("Terrain chunk variants: %d" % variants.size())
for variant: TerrainChunkVariant in variants:
print("\n", variant.stable_key())
for edge_value: int in TerrainChunkTopology.Edge.values():
var edge := edge_value as TerrainChunkTopology.Edge
var matches := PackedStringArray()
for other: TerrainChunkVariant in variants:
var opposite := TerrainChunkTopology.opposite_edge(edge)
if variant.profile(edge).matches(
other.profile(opposite),
MATCH_TOLERANCE,
):
matches.append(
"%s.%s"
% [
other.stable_key(),
TerrainChunkTopology.edge_name(opposite),
]
)
print(
" %s [%d points]: %s"
% [
TerrainChunkTopology.edge_name(edge),
variant.profile(edge).points.size(),
", ".join(matches) if not matches.is_empty() else "NONE",
]
)
var generator := TerrainChunkGenerator.new()
generator.catalog = CATALOG
generator.grid_size = Vector2i(5, 5)
generator.generation_seed = 13001
generator.generate_on_ready = false
generator.build_collision = false
generator.force_center_chunk_id = &"chunk_spawn"
generator.required_chunk_ids = PackedStringArray(
[
"chunk_spawn",
"chunk_0001",
"chunk_0002",
"chunk_0003",
"chunk_0004",
]
)
root.add_child(generator)
if generator.generate():
print("\nSeeded diagnostic layout:")
var keys := generator.placement_keys()
for row: int in generator.grid_size.y:
var cells := PackedStringArray()
for column: int in generator.grid_size.x:
cells.append(keys[row * generator.grid_size.x + column])
print(" ", " ".join(cells))
generator.free()
quit(0)

View file

@ -0,0 +1 @@
uid://di4yaor4f3s4e

View file

@ -0,0 +1,33 @@
extends Node3D
@onready var _generator: TerrainChunkGenerator = $TerrainChunkGenerator
@onready var _status: Label = $Instructions/Status
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed(&"ui_cancel"):
get_viewport().set_input_as_handled()
get_tree().quit()
return
var key_event := event as InputEventKey
if (
key_event != null
and key_event.pressed
and not key_event.echo
and key_event.physical_keycode == KEY_R
):
get_viewport().set_input_as_handled()
_generator.generation_seed += 1
_generator.generate()
func _on_generation_completed(summary: Dictionary) -> void:
_status.text = (
"Terrain generator diagnostic • seed %d%d chunks • "
+ "%d variants • %d backtracks\nR: regenerate • Esc/B: close"
) % [
int(summary["seed"]),
int(summary["chunk_count"]),
int(summary["variant_count"]),
int(summary["backtracks"]),
]

View file

@ -0,0 +1 @@
uid://0dmjswsm038h

View file

@ -0,0 +1,46 @@
[gd_scene load_steps=7 format=3]
[ext_resource type="Script" path="res://tests/manual/terrain_chunk_generator/terrain_chunk_generator_test.gd" id="1_test"]
[ext_resource type="Script" path="res://world/generation/terrain_chunk_generator.gd" id="2_generator"]
[ext_resource type="Resource" path="res://world/generation/chunks/terrain_chunk_catalog.tres" id="3_catalog"]
[ext_resource type="PackedScene" path="res://player/player.tscn" id="4_player"]
[ext_resource type="Environment" path="res://world/environment/netfishing_environment.tres" id="5_environment"]
[node name="TerrainChunkGeneratorTest" type="Node3D"]
script = ExtResource("1_test")
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = ExtResource("5_environment")
[node name="Sun" type="DirectionalLight3D" parent="."]
rotation_degrees = Vector3(-54, -32, 0)
light_color = Color(0.88, 0.94, 0.96, 1)
light_energy = 1.0
shadow_enabled = true
[node name="TerrainChunkGenerator" type="Node3D" parent="."]
script = ExtResource("2_generator")
catalog = ExtResource("3_catalog")
grid_size = Vector2i(5, 5)
generation_seed = 13001
build_collision = true
show_chunk_labels = false
force_center_chunk_id = &"chunk_spawn"
required_chunk_ids = PackedStringArray("chunk_spawn", "chunk_0001", "chunk_0002", "chunk_0003", "chunk_0004")
[node name="Player" parent="." instance=ExtResource("4_player")]
position = Vector3(0, 0.3, 0)
[node name="Instructions" type="CanvasLayer" parent="."]
layer = 20
[node name="Status" type="Label" parent="Instructions"]
offset_left = 18.0
offset_top = 18.0
offset_right = 930.0
offset_bottom = 74.0
text = "Terrain generator diagnostic\nR: regenerate • Esc/B: close"
theme_override_colors/font_color = Color(0.76, 0.88, 0.9, 1)
theme_override_font_sizes/font_size = 18
[connection signal="generation_completed" from="TerrainChunkGenerator" to="." method="_on_generation_completed"]