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:
parent
dc35389ecc
commit
ab78883db2
4 changed files with 61 additions and 66 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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...");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 11–16 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 11–16 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.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue