feat(@projects/@magic-civilization): 🎨 single-source biome_colors.json + DataLoader.get_biome_color (p2-87 phase 1a)
Establish ONE data source for biome render colour, lifting hex_renderer.gd's authoritative 69-entry palette (value-preserving, biome_id -> [r,g,b] 0-255). - public/games/age-of-dwarves/data/biome_colors.json — the single source. - DataLoader: _load_biome_colors() at theme load + get_biome_color(biome_id) with '_default' fallback then magenta sentinel. Additive only — no consumer rerouted yet (next phases: hex_renderer, minimap, proof scenes all read this + delete their hardcoded TERRAIN_COLORS dicts). Verified: headless load clean, biome_colors.json parses, 0 script errors. (data_loader.gd max-file-lines is pre-existing, tracked by p2-10k.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8fd3ef4ee3
commit
16bfb2ad31
2 changed files with 381 additions and 0 deletions
350
public/games/age-of-dwarves/data/biome_colors.json
Normal file
350
public/games/age-of-dwarves/data/biome_colors.json
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
{
|
||||
"_doc": "SINGLE SOURCE for biome render colour (biome_id -> [r,g,b] 0-255). Lifted value-preserving from hex_renderer.gd (p2-87). Consumed by hex_renderer + minimap + terrain proof scenes via DataLoader.get_biome_color(). '_default' is the fallback for unmapped biomes.",
|
||||
"colors": {
|
||||
"grassland": [
|
||||
115,
|
||||
173,
|
||||
76
|
||||
],
|
||||
"temperate_grassland": [
|
||||
140,
|
||||
184,
|
||||
76
|
||||
],
|
||||
"plains": [
|
||||
184,
|
||||
166,
|
||||
97
|
||||
],
|
||||
"chaparral": [
|
||||
158,
|
||||
143,
|
||||
89
|
||||
],
|
||||
"savanna": [
|
||||
199,
|
||||
184,
|
||||
107
|
||||
],
|
||||
"steppe": [
|
||||
166,
|
||||
158,
|
||||
115
|
||||
],
|
||||
"land": [
|
||||
128,
|
||||
153,
|
||||
97
|
||||
],
|
||||
"forest": [
|
||||
56,
|
||||
128,
|
||||
56
|
||||
],
|
||||
"temperate_forest": [
|
||||
46,
|
||||
122,
|
||||
56
|
||||
],
|
||||
"taiga": [
|
||||
76,
|
||||
115,
|
||||
89
|
||||
],
|
||||
"boreal_forest": [
|
||||
38,
|
||||
89,
|
||||
71
|
||||
],
|
||||
"jungle": [
|
||||
38,
|
||||
107,
|
||||
38
|
||||
],
|
||||
"tropical_rainforest": [
|
||||
15,
|
||||
97,
|
||||
38
|
||||
],
|
||||
"tropical_dry_forest": [
|
||||
107,
|
||||
128,
|
||||
56
|
||||
],
|
||||
"temperate_rainforest": [
|
||||
43,
|
||||
97,
|
||||
64
|
||||
],
|
||||
"enchanted_forest": [
|
||||
112,
|
||||
64,
|
||||
171
|
||||
],
|
||||
"montane_forest": [
|
||||
41,
|
||||
92,
|
||||
61
|
||||
],
|
||||
"cloud_forest": [
|
||||
51,
|
||||
112,
|
||||
87
|
||||
],
|
||||
"mangrove": [
|
||||
31,
|
||||
89,
|
||||
107
|
||||
],
|
||||
"desert": [
|
||||
224,
|
||||
209,
|
||||
140
|
||||
],
|
||||
"badlands": [
|
||||
184,
|
||||
107,
|
||||
71
|
||||
],
|
||||
"dust_plain": [
|
||||
184,
|
||||
120,
|
||||
74
|
||||
],
|
||||
"dune_field": [
|
||||
204,
|
||||
140,
|
||||
89
|
||||
],
|
||||
"canyon": [
|
||||
158,
|
||||
76,
|
||||
41
|
||||
],
|
||||
"ancient_lakebed": [
|
||||
140,
|
||||
115,
|
||||
82
|
||||
],
|
||||
"hills": [
|
||||
148,
|
||||
133,
|
||||
97
|
||||
],
|
||||
"mountain": [
|
||||
140,
|
||||
128,
|
||||
122
|
||||
],
|
||||
"mountains": [
|
||||
115,
|
||||
107,
|
||||
122
|
||||
],
|
||||
"highland": [
|
||||
158,
|
||||
143,
|
||||
112
|
||||
],
|
||||
"alpine_meadow": [
|
||||
128,
|
||||
153,
|
||||
122
|
||||
],
|
||||
"alpine_tundra": [
|
||||
158,
|
||||
166,
|
||||
143
|
||||
],
|
||||
"peak": [
|
||||
199,
|
||||
199,
|
||||
209
|
||||
],
|
||||
"basalt_highland": [
|
||||
76,
|
||||
64,
|
||||
56
|
||||
],
|
||||
"volcanic": [
|
||||
89,
|
||||
51,
|
||||
46
|
||||
],
|
||||
"volcano": [
|
||||
122,
|
||||
51,
|
||||
41
|
||||
],
|
||||
"volcanic_plains": [
|
||||
64,
|
||||
46,
|
||||
36
|
||||
],
|
||||
"lava_field": [
|
||||
204,
|
||||
41,
|
||||
10
|
||||
],
|
||||
"caldera": [
|
||||
115,
|
||||
26,
|
||||
20
|
||||
],
|
||||
"marsh": [
|
||||
102,
|
||||
133,
|
||||
89
|
||||
],
|
||||
"swamp": [
|
||||
51,
|
||||
71,
|
||||
31
|
||||
],
|
||||
"bog": [
|
||||
97,
|
||||
82,
|
||||
46
|
||||
],
|
||||
"wetland": [
|
||||
61,
|
||||
82,
|
||||
41
|
||||
],
|
||||
"oasis": [
|
||||
89,
|
||||
158,
|
||||
122
|
||||
],
|
||||
"tundra": [
|
||||
191,
|
||||
199,
|
||||
204
|
||||
],
|
||||
"snow": [
|
||||
235,
|
||||
240,
|
||||
245
|
||||
],
|
||||
"ice": [
|
||||
217,
|
||||
230,
|
||||
242
|
||||
],
|
||||
"permanent_ice": [
|
||||
199,
|
||||
219,
|
||||
232
|
||||
],
|
||||
"glacial": [
|
||||
230,
|
||||
237,
|
||||
247
|
||||
],
|
||||
"sea_ice": [
|
||||
191,
|
||||
217,
|
||||
242
|
||||
],
|
||||
"polar_desert": [
|
||||
184,
|
||||
186,
|
||||
173
|
||||
],
|
||||
"subterranean": [
|
||||
82,
|
||||
61,
|
||||
46
|
||||
],
|
||||
"cave": [
|
||||
46,
|
||||
41,
|
||||
33
|
||||
],
|
||||
"ocean": [
|
||||
38,
|
||||
76,
|
||||
140
|
||||
],
|
||||
"deep_ocean": [
|
||||
20,
|
||||
46,
|
||||
102
|
||||
],
|
||||
"coast": [
|
||||
64,
|
||||
122,
|
||||
166
|
||||
],
|
||||
"shallow_ocean": [
|
||||
46,
|
||||
97,
|
||||
184
|
||||
],
|
||||
"lake": [
|
||||
56,
|
||||
107,
|
||||
158
|
||||
],
|
||||
"inland_sea": [
|
||||
46,
|
||||
94,
|
||||
143
|
||||
],
|
||||
"river": [
|
||||
64,
|
||||
122,
|
||||
204
|
||||
],
|
||||
"pond": [
|
||||
97,
|
||||
158,
|
||||
209
|
||||
],
|
||||
"estuary": [
|
||||
64,
|
||||
115,
|
||||
133
|
||||
],
|
||||
"coral_reef": [
|
||||
38,
|
||||
158,
|
||||
148
|
||||
],
|
||||
"deep_water": [
|
||||
15,
|
||||
26,
|
||||
64
|
||||
],
|
||||
"shallow_water": [
|
||||
56,
|
||||
122,
|
||||
204
|
||||
],
|
||||
"lake_bed": [
|
||||
61,
|
||||
97,
|
||||
117
|
||||
],
|
||||
"lowland": [
|
||||
140,
|
||||
184,
|
||||
84
|
||||
],
|
||||
"midland": [
|
||||
122,
|
||||
158,
|
||||
82
|
||||
],
|
||||
"mana_node": [
|
||||
138,
|
||||
89,
|
||||
173
|
||||
],
|
||||
"_default": [
|
||||
122,
|
||||
122,
|
||||
122
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +58,8 @@ var _data: Dictionary = {}
|
|||
var _raw: Dictionary = {}
|
||||
var _ecology: DataLoaderEcologyScript = DataLoaderEcologyScript.new()
|
||||
var _worlds: DataLoaderWorldsScript = DataLoaderWorldsScript.new()
|
||||
## Single-source biome render colours (p2-87): biome_id -> [r,g,b] 0-255.
|
||||
var _biome_colors: Dictionary = {}
|
||||
|
||||
func _ready() -> void:
|
||||
for category: String in DATA_CATEGORIES:
|
||||
|
|
@ -74,6 +76,7 @@ func load_theme(theme_id: String) -> void:
|
|||
_load_from_base("res://public/resources", _RESOURCES_DIR_MAP)
|
||||
_load_from_base("res://public/games/%s/data" % theme_id, _WORLD_DIR_MAP)
|
||||
_apply_subscription_manifest(theme_id)
|
||||
_load_biome_colors(theme_id)
|
||||
_ecology.deserialize(_raw)
|
||||
BiomeRegistry.rebuild_from_data()
|
||||
_validate_unit_actions()
|
||||
|
|
@ -310,6 +313,34 @@ func get_data(category: String) -> Dictionary:
|
|||
func get_terrain(id: String) -> Dictionary:
|
||||
return _get_entry("terrain", id)
|
||||
|
||||
## Single-source biome render colour (p2-87). Reads biome_colors.json
|
||||
## (biome_id -> [r,g,b] 0-255), falling back to the '_default' entry, then to
|
||||
## opaque magenta if even that is missing (visible error, never silent black).
|
||||
func get_biome_color(biome_id: String) -> Color:
|
||||
var rgb: Array = _biome_colors.get(biome_id, _biome_colors.get("_default", [])) as Array
|
||||
if rgb != null and rgb.size() >= 3:
|
||||
return Color(float(rgb[0]) / 255.0, float(rgb[1]) / 255.0, float(rgb[2]) / 255.0)
|
||||
return Color(1.0, 0.0, 1.0)
|
||||
|
||||
|
||||
func _load_biome_colors(theme_id: String) -> void:
|
||||
_biome_colors = {}
|
||||
var path: String = "res://public/games/%s/data/biome_colors.json" % theme_id
|
||||
if not FileAccess.file_exists(path):
|
||||
push_warning("DataLoader: biome_colors.json not found at %s" % path)
|
||||
return
|
||||
var file: FileAccess = FileAccess.open(path, FileAccess.READ)
|
||||
if file == null:
|
||||
return
|
||||
var json: JSON = JSON.new()
|
||||
var err: Error = json.parse(file.get_as_text())
|
||||
file.close()
|
||||
if err != OK:
|
||||
push_error("DataLoader: biome_colors.json parse error: %s" % json.get_error_message())
|
||||
return
|
||||
if json.data is Dictionary and (json.data as Dictionary).has("colors"):
|
||||
_biome_colors = (json.data as Dictionary)["colors"] as Dictionary
|
||||
|
||||
func get_unit(id: String) -> Dictionary:
|
||||
return _get_entry("units", id)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue