feat(@projects/@magic-civilization): ✨ add fauna tile count tracking
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
4bf1d054a9
commit
c297a7fc13
3 changed files with 37 additions and 5 deletions
|
|
@ -2721,13 +2721,18 @@ func _snapshot_ecology() -> Dictionary:
|
|||
## mean + delta from Climate.get_canopy_summary, which wraps the Rust
|
||||
## GdEcologyPhysics bridge. Returns zeros before TurnManager has produced
|
||||
## a climate tick so the first seeded line still schema-validates.
|
||||
# p2-80: fauna populated-tile count from the live ecology engine — the count
|
||||
# the fauna overlay renders. >0 on a real worldgen game proves world-seeding
|
||||
# bootstrapped the living world end-to-end.
|
||||
var fauna_tiles: int = EcologyState.tile_densities().size()
|
||||
var climate: RefCounted = TurnManager.climate as RefCounted
|
||||
if climate == null or not climate.has_method("get_canopy_summary"):
|
||||
return {"flora_canopy_mean": 0.0, "flora_canopy_delta": 0.0}
|
||||
return {"flora_canopy_mean": 0.0, "flora_canopy_delta": 0.0, "fauna_tiles": fauna_tiles}
|
||||
var summary: Dictionary = climate.get_canopy_summary() as Dictionary
|
||||
return {
|
||||
"flora_canopy_mean": float(summary.get("mean", 0.0)),
|
||||
"flora_canopy_delta": float(summary.get("delta_since_last_turn", 0.0)),
|
||||
"fauna_tiles": fauna_tiles,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,23 @@ func clear() -> void:
|
|||
func _draw() -> void:
|
||||
if not visible or _densities.is_empty():
|
||||
return
|
||||
# Fog gate: fauna is only drawn on tiles the viewing player has explored, so
|
||||
# the lens never leaks creature positions on unseen terrain. Mirrors the fog
|
||||
# treatment of hex_renderer's flora layer. FORCE_DISABLE_FOGOFWAR (autoplay /
|
||||
# proof scenes) shows everything.
|
||||
var fog_off: bool = EnvConfig.get_bool("FORCE_DISABLE_FOGOFWAR")
|
||||
var game_map: RefCounted = GameState.get_game_map()
|
||||
var view_idx: int = _view_player_index()
|
||||
for pos: Vector2i in _densities:
|
||||
var density: float = float(_densities[pos])
|
||||
if density <= 0.0:
|
||||
continue
|
||||
if not fog_off and game_map != null:
|
||||
var tile: RefCounted = game_map.get_tile(pos)
|
||||
# Unexplored (visibility 0) tiles stay dark — no fauna leak. Explored
|
||||
# tiles (visible or fogged) show the density; the player has been there.
|
||||
if tile == null or int(tile.get_visibility(view_idx)) < 1:
|
||||
continue
|
||||
var t: float = clampf(density / _peak, 0.0, 1.0)
|
||||
# Lift off the floor so the dimmest populated tile is still legible.
|
||||
var fill_t: float = MIN_FILL_T + (1.0 - MIN_FILL_T) * t
|
||||
|
|
@ -76,6 +89,13 @@ func _draw() -> void:
|
|||
draw_colored_polygon(_hex_at(pos), color)
|
||||
|
||||
|
||||
## The player whose vision gates the overlay — the local/current player viewing
|
||||
## the map. Falls back to slot 0 if no current player is resolvable.
|
||||
func _view_player_index() -> int:
|
||||
var p: RefCounted = GameState.get_current_player()
|
||||
return int(p.index) if p != null else 0
|
||||
|
||||
|
||||
## Translate the shared flat-top hex polygon to the given tile's pixel origin.
|
||||
func _hex_at(pos: Vector2i) -> PackedVector2Array:
|
||||
var origin: Vector2 = HexUtilsScript.axial_to_pixel(pos)
|
||||
|
|
|
|||
|
|
@ -259,15 +259,22 @@ pub fn seed_base_trophic(
|
|||
seed: u64,
|
||||
) -> Vec<PopulationSlot> {
|
||||
let mut slots = Vec::new();
|
||||
if tile.habitat_suitability < config.habitat_abandon_threshold {
|
||||
return slots; // too hostile to bootstrap any starter population
|
||||
// Gate on terrain QUALITY, not `habitat_suitability`: the latter is
|
||||
// flora-derived (`canopy·0.4 + undergrowth·0.3 + fungi·0.3`, see
|
||||
// mc_climate::ecology::tick_habitat) and is ≈0 at genesis before any flora
|
||||
// has grown — gating seeding on it would reject the entire map at world
|
||||
// start (the chicken-and-egg that left the live world barren). `quality` is
|
||||
// a stable worldgen property (the same habitability proxy the original
|
||||
// EcologyInitializer used); quality 0 marks terrain too hostile for life.
|
||||
if tile.quality <= 0 {
|
||||
return slots;
|
||||
}
|
||||
let col = tile.col;
|
||||
let row = tile.row;
|
||||
let biome = tile.biome_label_id.as_str();
|
||||
// Starter cohort: comfortably above min_viable so the first dynamics tick
|
||||
// doesn't immediately extinguish it; scaled by habitat quality.
|
||||
let starter = (8.0 + 10.0 * tile.habitat_suitability).max(config.min_viable_population);
|
||||
// doesn't immediately extinguish it; scaled by terrain quality.
|
||||
let starter = (6.0 + 2.0 * tile.quality as f32).max(config.min_viable_population);
|
||||
|
||||
// Pick a biome-appropriate species from the library; fall back to a
|
||||
// procedurally-generated one (library picks are filtered on flora structure
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue