feat(game): add canonical game state refcounted handle

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-12 03:57:09 -07:00
parent f391a6ae10
commit 7b1e74c85a
2 changed files with 31 additions and 3 deletions

View file

@ -2,13 +2,13 @@
id: p2-72a
title: "Make `GdGameState` the canonical render source"
priority: p2
status: blocked
status: open
scope: game1
category: architecture
owner: simulator-infra
created: 2026-05-12
updated_at: 2026-05-11
blocked_by: [p2-72a-save-format-migration]
updated_at: 2026-05-12
blocked_by: []
follow_ups: [p2-72, p2-67]
---

View file

@ -101,6 +101,31 @@ var npc_buildings: Array = []
## Spatial index: "col,row" -> Array[Building] for quick tile lookups.
var _npc_buildings_by_tile: Dictionary = {}
## p2-72a Stage 4 — canonical Rust state handle. The long-lived GdGameState
## that renderers / UI / save-load read through. Created in `initialize_game`
## and `_ready`. Until view conversion lands (Waves 2-3), GDScript entity
## classes (Player/GameMap/Building/Unit/City) remain authoritative for
## per-field reads; once Wave 2-3 lands they become thin views over this
## handle and `state_changed` drives renderer redraw.
var _gd_state: RefCounted = null # GdGameState (RefCounted from gdext)
## Emitted after any state mutation that affects rendered output.
## Renderers connect to this to redraw on demand instead of polling.
signal state_changed
func _ensure_gd_state() -> void:
## Idempotent — instantiates _gd_state if not yet allocated.
if _gd_state != null:
return
_gd_state = ClassDB.instantiate("GdGameState") as RefCounted
if _gd_state == null:
push_error("GameState: GdGameState class not registered (gdext build missing?)")
func _ready() -> void:
_ensure_gd_state()
func initialize_game(settings: Dictionary) -> void:
game_settings = DEFAULT_SETTINGS.duplicate()
@ -122,6 +147,9 @@ func initialize_game(settings: Dictionary) -> void:
npc_buildings = []
_npc_buildings_by_tile = {}
_ensure_gd_state()
state_changed.emit()
var settings_seed: int = int(game_settings.get("seed", 0))
if settings_seed != 0:
map_seed = settings_seed