From c8debc316f30aa8d7dd68bbccceca7909656023d Mon Sep 17 00:00:00 2001 From: = <=> Date: Tue, 28 Apr 2026 17:41:18 +0200 Subject: [PATCH] Reworked border placement --- Scripts/WorldGeneration/Layer.cs | 86 ++++++++++---------------------- Scripts/WorldGeneration/WFC.cs | 28 +++++++++-- Scripts/WorldGeneration/World.cs | 10 +++- 3 files changed, 59 insertions(+), 65 deletions(-) diff --git a/Scripts/WorldGeneration/Layer.cs b/Scripts/WorldGeneration/Layer.cs index c97bb5d..4097e4c 100644 --- a/Scripts/WorldGeneration/Layer.cs +++ b/Scripts/WorldGeneration/Layer.cs @@ -13,6 +13,7 @@ public partial class Layer : Node3D int level; bool updateFailed = false; public bool hasContentGenerated = false; + public Vector2I gateCoordinate; // Called when the node enters the scene tree for the first time. public override void _Ready() @@ -40,7 +41,7 @@ public partial class Layer : Node3D } } - public void SetupLayer(int layerSize, int level, Dictionary tileMeshes) + public void SetupLayer(int layerSize, int level, Dictionary tileMeshes, Vector2I collapseOrigin) { this.layerSize = layerSize; this.level = level; @@ -49,7 +50,7 @@ public partial class Layer : Node3D int safetyCounter = 0; while (true) { - if (GenerateLayer()) break; + if (GenerateLayer(collapseOrigin)) break; ResetLayer(tileMeshes); safetyCounter++; if (safetyCounter > 1000) break; @@ -104,65 +105,30 @@ public partial class Layer : Node3D } } - private bool GenerateBorder() + private void GenerateBorder() { for (int x = 0; x < layerSize; x++) { - for (int y = 0; y < layerSize; y++) + for (int z = 0; z < layerSize; z++) { - if (x == 0 || y == 0 || x == layerSize - 1 || y == layerSize - 1) - { - var tile = tiles[x, y]; + if (!IsBorder(x, z)) + continue; - List possibilities = new(); + var tile = tiles[x, z]; + var possibilities = GetBorderPossibilities(x, z); - if (x == 0 && y == 0) - { - possibilities.Add("corner_down_right"); - } - else if (x == 0 && y == layerSize - 1) - { - possibilities.Add("corner_up_right"); - } - else if (x == layerSize - 1 && y == 0) - { - possibilities.Add("corner_down_left"); - } - else if (x == layerSize - 1 && y == layerSize - 1) - { - possibilities.Add("corner_up_left"); - } - else if (y == 0) - { - possibilities.Add("straight_left_right"); - possibilities.Add("t_down"); - } - else if (y == layerSize - 1) - { - possibilities.Add("straight_left_right"); - possibilities.Add("t_up"); - } - else if (x == 0) - { - possibilities.Add("straight_up_down"); - possibilities.Add("t_right"); - } - else if (x == layerSize - 1) - { - possibilities.Add("straight_up_down"); - possibilities.Add("t_left"); - } + if (possibilities.Count == 0) + continue; - string result = tile.Collapse(possibilities[rand.Next(0, possibilities.Count)]); - - if (result == "ERR") - return false; - - NewPropagate(new Vector2I(x, y)); - } + tile.Collapse(possibilities[rand.Next(possibilities.Count)]); + Propagate(new Vector2I(x, z)); } } - return true; + } + + private bool IsBorder(int x, int z) + { + return x == 0 || z == 0 || x == layerSize - 1 || z == layerSize - 1; } private void GenerateNecessaryTiles() @@ -177,30 +143,28 @@ public partial class Layer : Node3D if (tiles[posX, posY].tileMeshes.ContainsKey("gate")) { tiles[posX, posY].Collapse("gate"); - NewPropagate(new Vector2I(posX, posY)); + gateCoordinate = new Vector2I(posX, posY); + Propagate(gateCoordinate); break; } } } - public bool GenerateLayer() + public bool GenerateLayer(Vector2I collapseOrigin) { bool result = true; int safetyCounter = 0; - if (!GenerateBorder()) - { - return false; - } + GenerateBorder(); GenerateNecessaryTiles(); - Vector2I position = GetSmallestPossibilities(); + Vector2I position = tiles[collapseOrigin.X, collapseOrigin.Y].collapsedMesh == null ? collapseOrigin : GetSmallestPossibilities(); while (true) { string keyword = tiles[position.X, position.Y].Collapse(""); if (keyword == "ERR") return false; if (keyword != "") { - NewPropagate(position); + Propagate(position); if (updateFailed) break; position = GetSmallestPossibilities(); if (position == new Vector2(-100, -100)) @@ -219,7 +183,7 @@ public partial class Layer : Node3D return result; } - private void NewPropagate(Vector2I startPos) + private void Propagate(Vector2I startPos) { Queue queue = new Queue(); queue.Enqueue(startPos); diff --git a/Scripts/WorldGeneration/WFC.cs b/Scripts/WorldGeneration/WFC.cs index d25d576..f7e315a 100644 --- a/Scripts/WorldGeneration/WFC.cs +++ b/Scripts/WorldGeneration/WFC.cs @@ -36,7 +36,7 @@ public class WFC public static Dictionary> tileConnections = new Dictionary> { - ["t_right"] = new() { Direction.Backward, Direction.Forward, Direction.Right , Direction.Up}, + ["t_right"] = new() { Direction.Backward, Direction.Forward, Direction.Right, Direction.Up }, ["t_left"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Up }, ["t_up"] = new() { Direction.Left, Direction.Right, Direction.Backward, Direction.Up }, ["t_down"] = new() { Direction.Left, Direction.Right, Direction.Forward, Direction.Up }, @@ -54,8 +54,8 @@ public class WFC ["corner_down_left"] = new() { Direction.Forward, Direction.Left, Direction.Up }, ["corner_down_right"] = new() { Direction.Forward, Direction.Right, Direction.Up }, - ["junction"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up}, - ["gate"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up, Direction.Down} + ["junction"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up }, + ["gate"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up, Direction.Down } }; public static Dictionary weights = new() @@ -196,4 +196,26 @@ public class WFC pos.X < layerSize && pos.Y < layerSize; } + + public static List GetBorderPossibilities(int x, int z) + { + bool left = x == 0; + bool right = x == GameData.layerSize - 1; + bool top = z == 0; + bool bottom = z == GameData.layerSize - 1; + + // Corners + if (left && top) return new() { "corner_down_right" }; + if (left && bottom) return new() { "corner_up_right" }; + if (right && top) return new() { "corner_down_left" }; + if (right && bottom) return new() { "corner_up_left" }; + + // Edges + if (top) return new() { "straight_left_right", "t_down" }; + if (bottom) return new() { "straight_left_right", "t_up" }; + if (left) return new() { "straight_up_down", "t_right" }; + if (right) return new() { "straight_up_down", "t_left" }; + + return new(); + } } diff --git a/Scripts/WorldGeneration/World.cs b/Scripts/WorldGeneration/World.cs index 5883251..c6603ea 100644 --- a/Scripts/WorldGeneration/World.cs +++ b/Scripts/WorldGeneration/World.cs @@ -101,7 +101,15 @@ public partial class World : Node3D { layerNode = layerPrefab.Instantiate(); AddChild(layerNode); - layerNode.SetupLayer(layerSize, layer, tileMeshes); + if (layer == 0) + { + layerNode.SetupLayer(layerSize, layer, tileMeshes, new Vector2I()); + } + else + { + layerNode.SetupLayer(layerSize, layer, tileMeshes, map[layer-1].gateCoordinate); + } + map[layer] = layerNode; } }