diff --git a/Tools/Scripts/MapGenerator.cs b/Tools/Scripts/MapGenerator.cs index 54c3c73..adc69a5 100644 --- a/Tools/Scripts/MapGenerator.cs +++ b/Tools/Scripts/MapGenerator.cs @@ -625,9 +625,7 @@ public partial class MapGenerator : TextureRect GD.Print($"[A*] Starting Logistics Pathfinding for {MapSize}x{MapSize} world..."); _highwayPaths.Clear(); _branchPaths.Clear(); _ruggedPaths.Clear(); _trailPaths.Clear(); - // RoadPathGrid is a stock AStarGrid2D with a scaled-up distance estimate, so the - // search stops flood-filling the island for every road. See the class for why. - AStarGrid2D astar = new RoadPathGrid(); + AStarGrid2D astar = new AStarGrid2D(); astar.Region = new Rect2I(0, 0, MapSize, MapSize); astar.CellSize = new Vector2I(1, 1); astar.DiagonalMode = AStarGrid2D.DiagonalModeEnum.OnlyIfNoObstacles; @@ -838,23 +836,6 @@ public partial class MapGenerator : TextureRect } } - /// - /// How much extra a step costs near an already-drawn road. This is what stops new - /// roads from lying on top of old ones — it is SEPARATION, not terrain avoidance, - /// so it is unrelated to the mountain/beach/wasteland weights. - /// - /// It used to be 10,000, which was far past "discourage" — a normal step costs 1, - /// so it made the ground near a road effectively infinite. That wrecked the search: - /// every later road had to weigh routes costing tens of thousands, which is exactly - /// the situation A* handles by giving up on being clever and searching everything. - /// Worse, it compounded — each road drawn made the next one slower. - /// - /// 250 still means "strongly prefer not to run alongside an existing road" (250x a - /// normal step) without dwarfing the search. Raise it if parallel roads crowd - /// together; lower it if roads take silly detours to avoid each other. - /// - private const float ROAD_REPULSION_PENALTY = 250f; - private void PenalizePath(AStarGrid2D astar, Vector2[] path, int radius) { int step = Mathf.Max(1, radius / 2); @@ -866,7 +847,8 @@ public partial class MapGenerator : TextureRect int ny = Mathf.Clamp((int)p.Y + dy, 0, MapSize - 1); var cell = new Vector2I(nx, ny); if (!astar.IsPointSolid(cell)) { - astar.SetPointWeightScale(cell, astar.GetPointWeightScale(cell) + ROAD_REPULSION_PENALTY); + // The true Iron Curtain + astar.SetPointWeightScale(cell, astar.GetPointWeightScale(cell) + 10000f); } } } @@ -968,44 +950,6 @@ public partial class MapGenerator : TextureRect } // Place this at the very bottom of the file! -/// -/// The road pathfinder's grid, with one change from stock: a scaled-up estimate. -/// -/// WHY THIS EXISTS. A* explores outward from the start until the cheapest route it -/// has found is provably the best. It decides how far to keep looking by comparing -/// what a route has cost so far against an ESTIMATE of what remains. Godot's stock -/// estimate is plain straight-line distance — it assumes every step costs 1. -/// -/// Our steps don't cost 1. A step through mountains costs up to 401, and a step near -/// an existing road used to cost 10,001. So the estimate was wildly optimistic about -/// the remaining journey, and A* responded the only way it can: by refusing to rule -/// anything out and searching almost the whole island for every single road. -/// -/// Multiplying the estimate makes the search commit to a direction sooner. It's a -/// well-known trade ("weighted A*"): paths are allowed to be up to HEURISTIC_WEIGHT -/// times more expensive than the theoretical best, in exchange for exploring far less. -/// We want believable roads, not provably-optimal ones, so that's a good trade. -/// -/// It does NOT make roads climb mountains. Crossing a ridge costs hundreds of times -/// more than walking around it — a 3x bias nowhere near pays for that. -/// -public partial class RoadPathGrid : AStarGrid2D -{ - /// - /// How strongly the search commits toward the goal. - /// 1.0 = stock behaviour: guaranteed-shortest, explores enormously. - /// 3.0 = default: still routes sensibly around terrain, explores far less. - /// higher = faster still, but paths get progressively less considered. - /// Raise it if generation is still slow; lower it if roads start looking careless. - /// - public const float HEURISTIC_WEIGHT = 3.0f; - - public override float _EstimateCost(Vector2I fromId, Vector2I toId) - { - return fromId.DistanceTo(toId) * HEURISTIC_WEIGHT; - } -} - public partial class MapDrawProxy : Control { public MapGenerator Source;