feat(engine): ✨ Implement TurnManager and WorldSimState for core turn-based simulation and world state management
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
5a6f9ffb67
commit
e9b76ecdd6
3 changed files with 85 additions and 0 deletions
|
|
@ -293,6 +293,14 @@ func next_player() -> void:
|
|||
var fauna_grid: RefCounted = climate_node.get("_grid") as RefCounted
|
||||
if fauna_grid != null:
|
||||
EcologyState.tick(fauna_grid, GameState.map_seed + GameState.turn_number)
|
||||
# Increment 3b: world-event dispatch (geological / biological /
|
||||
# anomalous) against the SAME live grid, after climate + ecology
|
||||
# ticks. Accumulates per-tile eco-damage into WorldsimState's
|
||||
# eco_map (persisted in the save). Production thresholds make
|
||||
# events deliberately rare; this is the missing worldsim layer.
|
||||
WorldsimState.dispatch(
|
||||
fauna_grid, GameState.turn_number, GameState.map_seed
|
||||
)
|
||||
GameState.current_player_index = 0
|
||||
GameState.turn_number += 1
|
||||
# Check victory conditions after all players have moved
|
||||
|
|
|
|||
76
src/game/engine/src/autoloads/worldsim_state.gd
Normal file
76
src/game/engine/src/autoloads/worldsim_state.gd
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
extends Node
|
||||
|
||||
## Session-scoped GdWorldSim singleton (Increment 3b).
|
||||
##
|
||||
## Owns the continuous-worldsim EVENT layer that runs after the per-turn climate
|
||||
## + ecology ticks: geological / biological / anomalous event dispatch, which
|
||||
## accumulates per-tile eco-damage into an owned `eco_map`. This is the layer
|
||||
## the live `turn_manager.gd::next_player()` was missing — climate and ecology
|
||||
## (incl. migration) already tick via ClimatePhysics + EcologyState, but no
|
||||
## world events fired in-game.
|
||||
##
|
||||
## Lifecycle:
|
||||
## _ready() → reset() builds a fresh GdWorldSim + loads thresholds
|
||||
## dispatch(grid, seed) → one world-event pass against the LIVE grid
|
||||
## (read-modify-write; see GdWorldSim::dispatch_on_grid)
|
||||
## to_save_json()/restore_from_save_json() → eco_map save round-trip
|
||||
##
|
||||
## Thresholds are loaded from the canonical JSON pack (Rail 2) at production
|
||||
## rates — events are deliberately rare (~0.003/turn seismic). Proof scenes /
|
||||
## tests boost thresholds so events fire reliably in a short run.
|
||||
|
||||
const GEO_THRESHOLDS_PATH: String = "res://public/resources/events/geological_thresholds.json"
|
||||
const BIO_THRESHOLDS_PATH: String = (
|
||||
"res://public/games/age-of-dwarves/data/balance/biological_events.json"
|
||||
)
|
||||
|
||||
var worldsim: RefCounted = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
reset()
|
||||
|
||||
|
||||
## Discard the current GdWorldSim and build a fresh one with production
|
||||
## thresholds loaded. Called on new game / load so eco_map does not carry across
|
||||
## sessions (the saved eco_map is injected via restore_from_save_json on load).
|
||||
func reset() -> void:
|
||||
if not ClassDB.class_exists("GdWorldSim"):
|
||||
worldsim = null
|
||||
return
|
||||
worldsim = ClassDB.instantiate("GdWorldSim") as RefCounted
|
||||
var geo: String = FileAccess.get_file_as_string(GEO_THRESHOLDS_PATH)
|
||||
var bio: String = FileAccess.get_file_as_string(BIO_THRESHOLDS_PATH)
|
||||
# Anomalous has no authored JSON yet — pass "" to keep Rust Default.
|
||||
worldsim.call("load_thresholds_from_json", geo, bio, "")
|
||||
|
||||
|
||||
## Run one world-event dispatch pass against the live shared grid. Caller is
|
||||
## `turn_manager.gd::next_player()` after the climate + ecology ticks. Returns
|
||||
## the number of events dispatched this turn.
|
||||
func dispatch(grid: RefCounted, turn: int, seed: int) -> int:
|
||||
if worldsim == null or grid == null:
|
||||
return 0
|
||||
return int(worldsim.call("dispatch_on_grid", grid, turn, seed))
|
||||
|
||||
|
||||
## Serialize the eco-damage map for the save envelope. Empty string when no
|
||||
## worldsim is active.
|
||||
func to_save_json() -> String:
|
||||
if worldsim == null:
|
||||
return ""
|
||||
return String(worldsim.call("eco_map_to_json"))
|
||||
|
||||
|
||||
## Restore the eco-damage map from a save envelope payload. No-op on empty input.
|
||||
func restore_from_save_json(json: String) -> void:
|
||||
if worldsim == null or json.is_empty():
|
||||
return
|
||||
worldsim.call("restore_eco_map_from_json", json)
|
||||
|
||||
|
||||
## Tiles carrying accumulated eco-damage — cheap probe for HUD / tests.
|
||||
func eco_damage_tile_count() -> int:
|
||||
if worldsim == null:
|
||||
return 0
|
||||
return int(worldsim.call("eco_map_len"))
|
||||
1
src/game/engine/src/autoloads/worldsim_state.gd.uid
Normal file
1
src/game/engine/src/autoloads/worldsim_state.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b8d8hc2h052uk
|
||||
Loading…
Add table
Reference in a new issue