Pre-rewrite reference checkpoint — final state of the salvage/prototype codebase (C0/C0b complete)

The rewrite (D-049) starts from a clean slate; this commit is the reference
implementation of the graduated design.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stewart Howe 2026-08-18 20:54:20 -04:00
parent dc35389ecc
commit ab78883db2
4 changed files with 61 additions and 66 deletions

View file

@ -10,7 +10,6 @@ ground_bottom_color = Color(0.16, 0.15, 0.14, 1)
ground_horizon_color = Color(0.58, 0.56, 0.5, 1) ground_horizon_color = Color(0.58, 0.56, 0.5, 1)
ground_curve = 0.05 ground_curve = 0.05
sun_angle_max = 12.0 sun_angle_max = 12.0
sun_curve = 0.15
[sub_resource type="Sky" id="Sky_main0"] [sub_resource type="Sky" id="Sky_main0"]
sky_material = SubResource("ProceduralSkyMaterial_sky0") sky_material = SubResource("ProceduralSkyMaterial_sky0")
@ -27,7 +26,6 @@ script = ExtResource("1_r150o")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1569534216] [node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1569534216]
transform = Transform3D(-0.7071068, 0, 0.7071068, 0.5572077, 0.6156615, 0.5572077, -0.4353384, 0.7880108, -0.4353384, 0, 0, 0) transform = Transform3D(-0.7071068, 0, 0.7071068, 0.5572077, 0.6156615, 0.5572077, -0.4353384, 0.7880108, -0.4353384, 0, 0, 0)
light_energy = 1.0
shadow_enabled = true shadow_enabled = true
directional_shadow_max_distance = 2500.0 directional_shadow_max_distance = 2500.0

View file

@ -84,11 +84,8 @@ namespace IslaApocalypse.Server
break; break;
} }
} }
// Manual Test point
// Old original png map coords // Vector2 capitolPos = new Vector2(6852, 6241);
// Vector2 capitolPos = new Vector2(2405, 3296); // hardcoded for now since we know exactly where it is in this seed, which is the "paradise" biome hub
// New Manual Test point
// Vector2 capitolPos = new Vector2(4487, 4424);
GD.Print($"[Server] Capitol found at {capitolPos}. Generating chunks..."); GD.Print($"[Server] Capitol found at {capitolPos}. Generating chunks...");

View file

@ -1,8 +1,8 @@
{ {
"WorldSeed": 1409879727, "WorldSeed": 1280587109,
"MapProfile": "8K", "MapProfile": "8K",
"TownDensity": "Normal", "TownDensity": "Normal",
"ChunkRadius": 32, "ChunkRadius": 64,
"SeaLevelModel": "flat", "SeaLevelModel": "flat",
"SeaLevelValue": 0.15 "SeaLevelValue": 0.15
} }

View file

@ -1,57 +1,57 @@
# MapGenerator.cs - Architecture & Historical Decisions # MapGenerator.cs - Architecture & Historical Decisions
**Date:** March 2026 **Date:** March 2026
**Purpose:** Generates the 2D topographical blueprint (Topography, Biomes, Cities, and Road Networks) **Purpose:** Generates the 2D topographical blueprint (Topography, Biomes, Cities, and Road Networks)
to be parsed and translated into a 3D Voxel World. to be parsed and translated into a 3D Voxel World.
> ⚠ **Historical document — read it as a record of decisions, not as current spec.** It was written > ⚠ **Historical document — read it as a record of decisions, not as current spec.** It was written
> when the map was 4096², and references to that size throughout should be read as "the map size of > when the map was 4096², and references to that size throughout should be read as "the map size of
> the day". **Map size is now config-driven** (`MapProfile` in `ServerConfig.json`; 8192 by default), > the day". **Map size is now config-driven** (`MapProfile` in `ServerConfig.json`; 8192 by default),
> and the reasoning it describes — scaling everything off `MapSize` rather than hardcoding — is > and the reasoning it describes — scaling everything off `MapSize` rather than hardcoding — is
> exactly what makes that work. > exactly what makes that work.
> >
> For the current behaviour see `Tools/Scripts/README.md`. For design rationale and the decisions > For the current behaviour see `Tools/Scripts/README.md`. For design rationale and the decisions
> behind the project, see the design vault. > behind the project, see the design vault.
--- ---
## 1. Topography & The Impact Crater ## 1. Topography & The Impact Crater
* **Base Generation:** Uses `FastNoiseLite` to generate standard heightmaps and temperature maps, which drive dynamic biomes. * **Base Generation:** Uses `FastNoiseLite` to generate standard heightmaps and temperature maps, which drive dynamic biomes.
* **Dynamic Sea Level:** Sea level is calculated based on the temperature map (simulating ice caps/equatorial swelling). * **Dynamic Sea Level:** Sea level is calculated based on the temperature map (simulating ice caps/equatorial swelling).
* **The Crater:** A massive (radius 400) blast zone is forced along the northern coast. Surrounding it is a `Biome.Wasteland` with a noise-driven "fray" on its borders. * **The Crater:** A massive (radius 400) blast zone is forced along the northern coast. Surrounding it is a `Biome.Wasteland` with a noise-driven "fray" on its borders.
* **Design Choice:** We allowed the crater to occasionally spawn slightly inland rather than strictly on the beach. This creates natural topographical "pinch points" that will result in highly memorable, claustrophobic 3D driving mechanics. * **Design Choice:** We allowed the crater to occasionally spawn slightly inland rather than strictly on the beach. This creates natural topographical "pinch points" that will result in highly memorable, claustrophobic 3D driving mechanics.
## 2. City Placement & The Capitol Tether ## 2. City Placement & The Capitol Tether
* **The Challenge:** The Capitol City must spawn inside the radioactive Wasteland, but it MUST be connected to the contiguous mainland for the A* highway to reach it. Early iterations spawned the Capitol underwater or stranded it on offshore islands caused by the Wasteland noise bleeding over the ocean. * **The Challenge:** The Capitol City must spawn inside the radioactive Wasteland, but it MUST be connected to the contiguous mainland for the A* highway to reach it. Early iterations spawned the Capitol underwater or stranded it on offshore islands caused by the Wasteland noise bleeding over the ocean.
* **The Solution (Smart Tiered Spawner):** We abandoned a rigid `while` loop in favor of a tiered attempt system. * **The Solution (Smart Tiered Spawner):** We abandoned a rigid `while` loop in favor of a tiered attempt system.
* **Tier 1:** Searches for ideal (Wasteland + Coastal + Mainland). * **Tier 1:** Searches for ideal (Wasteland + Coastal + Mainland).
* **Tier 2:** Relaxes the coastal requirement. * **Tier 2:** Relaxes the coastal requirement.
* **Tier 3:** Scans the entire array for the closest valid pixel to the impact center. * **Tier 3:** Scans the entire array for the closest valid pixel to the impact center.
* **Tier 4 (Doomsday):** Walks strictly south until it hits the mainland. * **Tier 4 (Doomsday):** Walks strictly south until it hits the mainland.
## 3. The Pathfinding Wars (A* Road Optimization) ## 3. The Pathfinding Wars (A* Road Optimization)
The road network generation was the hardest logistical hurdle. Standard grid-based `AStarGrid2D` math does not scale cleanly to a 4096 map. The road network generation was the hardest logistical hurdle. Standard grid-based `AStarGrid2D` math does not scale cleanly to a 4096 map.
### Phase 1: The 16-Minute Bottleneck ### Phase 1: The 16-Minute Bottleneck
* **The Flaw:** To force the highway to create a large loop connecting our 3 Hubs, we used an `ApplyRepulsion` function that penalized pixels in a 400px radius around the first drawn road. * **The Flaw:** To force the highway to create a large loop connecting our 3 Hubs, we used an `ApplyRepulsion` function that penalized pixels in a 400px radius around the first drawn road.
* **The Math:** Repelling a 2,000-point path with a 400px radius resulted in over **1.3 Billion** nested loop iterations. The CPU choked, and generation took 1116 minutes. * **The Math:** Repelling a 2,000-point path with a 400px radius resulted in over **1.3 Billion** nested loop iterations. The CPU choked, and generation took 1116 minutes.
* **The Result:** Unusable generation times, extreme stair-stepping (zig-zagging), and roads cutting straight over mountains. * **The Result:** Unusable generation times, extreme stair-stepping (zig-zagging), and roads cutting straight over mountains.
### Phase 2: The Speedrun & The Double-Back ### Phase 2: The Speedrun & The Double-Back
* **The Flaw:** We ripped out the repulsion completely to save CPU time, dropping the render to **1 minute**. * **The Flaw:** We ripped out the repulsion completely to save CPU time, dropping the render to **1 minute**.
* **The Result:** Because A* is deterministic, the pathfinder just used the exact same pixels to return to the start, completely breaking the 3-point loop and causing the highway to double back on itself. * **The Result:** Because A* is deterministic, the pathfinder just used the exact same pixels to return to the start, completely breaking the 3-point loop and causing the highway to double back on itself.
### Phase 3: The Over-Engineered Spaghetti (The LLM Trap) ### Phase 3: The Over-Engineered Spaghetti (The LLM Trap)
* **The Flaw:** We brought in an external LLM to fix the pathing. It introduced a "Midland Sweet Spot" to force roads off the coast, and a "Daisy-Chain" mechanic for branch roads. * **The Flaw:** We brought in an external LLM to fix the pathing. It introduced a "Midland Sweet Spot" to force roads off the coast, and a "Daisy-Chain" mechanic for branch roads.
* **The Result:** The highway started tracing narrow elevation contour lines like a drunk driver. The branch roads turned into a game of "Snake," meandering wildly to connect to each other instead of taking logical paths to the highway. Furthermore, adding a soft weight to the crater combined with our loop repulsion created a "Wasteland Phobia" where the A* algorithm mathematically folded and refused to complete the loop. * **The Result:** The highway started tracing narrow elevation contour lines like a drunk driver. The branch roads turned into a game of "Snake," meandering wildly to connect to each other instead of taking logical paths to the highway. Furthermore, adding a soft weight to the crater combined with our loop repulsion created a "Wasteland Phobia" where the A* algorithm mathematically folded and refused to complete the loop.
### Phase 4: The Tactical Revert (Our Final State) ### Phase 4: The Tactical Revert (Our Final State)
We executed a deliberate tactical revert, stripping out the over-engineered LLM spaghetti and keeping only robust, simple math: We executed a deliberate tactical revert, stripping out the over-engineered LLM spaghetti and keeping only robust, simple math:
1. **Direct Branches:** Black roads path directly to the closest highway pixel. No daisy-chaining. 1. **Direct Branches:** Black roads path directly to the closest highway pixel. No daisy-chaining.
2. **The Iron Curtain Repulsion:** We restored a `+10000f` penalty to old highway segments with a radius of 120px to physically force the 3-point loop. We optimized it by only applying the penalty to every `step` (half the radius) pixel. Render time remains at ~1 minute. 2. **The Iron Curtain Repulsion:** We restored a `+10000f` penalty to old highway segments with a radius of 120px to physically force the 3-point loop. We optimized it by only applying the penalty to every `step` (half the radius) pixel. Render time remains at ~1 minute.
3. **Simple Elevation Weights:** Instead of a complex U-curve, we use `Mathf.Pow(normalizedElevation, 3.0f) * 400.0f` to aggressively punish mountains, and a flat `+15.0f` penalty to gently push roads off the beach sand. 3. **Simple Elevation Weights:** Instead of a complex U-curve, we use `Mathf.Pow(normalizedElevation, 3.0f) * 400.0f` to aggressively punish mountains, and a flat `+15.0f` penalty to gently push roads off the beach sand.
## 4. The AAA Smoothing Pipeline ## 4. The AAA Smoothing Pipeline
Standard A* creates jagged, octagonal stair-steps that look terrible in a 3D voxel world. We completely eradicated this using a 2-step geometric smoothing pipeline: Standard A* creates jagged, octagonal stair-steps that look terrible in a 3D voxel world. We completely eradicated this using a 2-step geometric smoothing pipeline:
1. **Ramer-Douglas-Peucker (RDP):** Decimates the raw A* path, removing thousands of useless straight-line grid points and leaving only the major turns. 1. **Ramer-Douglas-Peucker (RDP):** Decimates the raw A* path, removing thousands of useless straight-line grid points and leaving only the major turns.
2. **Chaikin's Algorithm:** Performs 4 passes of corner-cutting on the decimated points, resulting in buttery-smooth, sweeping, AAA-style highway curves ready for 3D mesh generation. 2. **Chaikin's Algorithm:** Performs 4 passes of corner-cutting on the decimated points, resulting in buttery-smooth, sweeping, AAA-style highway curves ready for 3D mesh generation.