extends Node ## Runtime entity registry + tile-related sim state. ## ## All gameplay entities (pawns, items, furniture, animals, corpses) live here. ## TileMap data is owned by the world-view scene; World holds the *indirect* ## state (designation queue, dirty-haul set, zone records, etc.) that doesn't ## belong on the TileMap itself. ## ## See docs/architecture.md. # Phase 2 — pawn registry. items/furniture/animals/corpses arrive in later phases. var pawns: Array[Pawn] = [] # Phase 3 — work providers (e.g. RestProvider, ChopProvider, HaulingProvider). # World scene registers them on _ready. Decision.pick_next_job() iterates by .priority desc. var work_providers: Array = [] # Phase 4 — harvestables + items + stockpiles. Entities call register_*/unregister_* # from their _ready/_exit_tree. Phase 16 will add stable IDs and persistence wiring. var trees: Array = [] # Array of Tree var rocks: Array = [] # Array of Rock var items: Array = [] # Array of Item (on-floor stacks) var stockpiles: Array = [] # Array of StorageDestination (StockpileZone for now; containers Phase 5) # Phase 4 — pathfinder reference exposed for entity code that needs walkability # checks (e.g. Tree.fell() picking neighbour tiles for wood drops). The actual # Pathfinder node lives on the World scene as a child; the scene sets this in # its _ready(). Don't access before the world scene is mounted. var pathfinder = null # Phase 4 — hauling dirty set. Keys are Items, value is unused (we just use .keys()). # An Item is added when it spawns (Tree.fell, Rock.mined, workbench drop, ...) # and removed when it lands at its highest-priority valid destination. # HaulingProvider.sweep_for_better_destinations() re-marks items when a higher # priority stockpile opens up (the priority cascade per design.md). var items_needing_haul: Dictionary = {} func register_work_provider(wp) -> void: assert(wp != null, "World.register_work_provider: provider is null") if not work_providers.has(wp): work_providers.append(wp) func clear_work_providers() -> void: work_providers.clear() func register_pawn(p: Pawn) -> void: assert(p != null, "World.register_pawn: pawn is null") if pawns.has(p): return pawns.append(p) func unregister_pawn(p: Pawn) -> void: pawns.erase(p) func pawn_at_tile(tile: Vector2i) -> Pawn: for p in pawns: if p.tile == tile: return p return null func clear_pawns() -> void: # For save-load / new-game flow in Phase 16. pawns.clear() # ── Phase 4: harvestables + items + stockpiles ────────────────────────────── func register_tree(t) -> void: if not trees.has(t): trees.append(t) func unregister_tree(t) -> void: trees.erase(t) func register_rock(r) -> void: if not rocks.has(r): rocks.append(r) func unregister_rock(r) -> void: rocks.erase(r) func register_item(it) -> void: if items.has(it): return items.append(it) # Newly-spawned items always start as "needs haul" — HaulingProvider will # clear the flag once the item lands in its highest-priority destination. items_needing_haul[it] = true func unregister_item(it) -> void: items.erase(it) items_needing_haul.erase(it) func register_stockpile(s) -> void: if not stockpiles.has(s): stockpiles.append(s) func unregister_stockpile(s) -> void: stockpiles.erase(s) func mark_item_needs_haul(it) -> void: items_needing_haul[it] = true func clear_item_haul_flag(it) -> void: items_needing_haul.erase(it)