extends Node ## Pure signal hub — notification-only, no state, no callbacks back into singletons. ## ## Subsystems mutate themselves; this bus only spreads the news. Add signals as ## features land — keep this file readable. See docs/architecture.md. # Sim signal sim_tick(tick_number: int) ## Emitted once per sim tick at the current speed. signal speed_changed(new_speed: int) ## Emitted when Sim.current_speed changes; value is Speed enum cast to int. # Phase 2 will add pawn-state signals (selected, deselected, walking, …). # Phase 5 — Designation paint mode. signal designation_added(cell: Vector2i, tool: StringName) ## Ghost placed + job queued. signal designation_cleared(cell: Vector2i) ## Ghost removed (job cancelled). # Phase 8 — Mood system. signal pawn_mood_changed(pawn, mood: float) ## Emitted by Pawn._recompute_mood() whenever mood is recalculated. # Phase 9 — HP + Status system. signal pawn_took_damage(pawn, amount: float) ## Emitted by Pawn.take_damage() after HP is reduced. signal pawn_status_added(pawn, status) ## Emitted by Pawn.add_status() when a new status is appended. signal pawn_status_removed(pawn, status) ## Emitted by Pawn.remove_status_by_id() when a status is dropped. # Phase 12 — Seasons + Weather. signal season_changed(season: StringName) ## Emitted by Clock when current_season() rolls over (Spring → Summer → Autumn → Winter). signal weather_changed(weather: StringName) ## Emitted by Weather autoload when the daily roll resolves to a new weather kind. # Phase 13 — Rooms + Roofing + Beauty + Dirtiness + Cleaning. signal room_changed(room_id: int) ## Emitted when a room is created, destroyed, or recomputed (id may be invalid post-destroy). signal room_too_large(top_left: Vector2i, cell_count: int) ## Emitted when BFS hits ROOM_MAX_CELLS — surfaces the "split with interior wall" banner. signal tile_beauty_changed(tile: Vector2i, beauty: float) ## Emitted when beauty recomputes for a tile (Phase 13 beauty system). signal tile_dirtiness_changed(tile: Vector2i, dirt: float) ## Emitted when dirtiness crosses a tier threshold (clean/dirty/filthy). # Phase 14 — Death + corpses + burial. signal pawn_died(pawn, cause: StringName) ## Emitted right before Pawn is unregistered; corpse spawn handler listens here. signal corpse_spawned(corpse) ## Emitted when a Corpse entity is added to the world (right after pawn_died handler). signal corpse_buried(corpse, grave_marker) ## Emitted when a corpse reaches a GraveSlot and converts to a permanent GraveMarker. signal corpse_cremated(corpse, pyre) ## Emitted when a corpse is consumed by a cremation pyre recipe. signal corpse_rotted_away(corpse) ## Emitted when an un-handled corpse hits decay 100 and is destroyed. # Phase 15 — Storyteller. signal storyteller_event_fired(event) ## Emitted when Storyteller selects an event and is about to display it (carries EventDef). signal storyteller_event_resolved(event, choice_index: int) ## Emitted after the player dismisses or chooses (choice 0 = dismiss/first option). signal storyteller_tension_changed(tension: float) ## Emitted when running tension score changes (0..100). signal storyteller_ghost_state_entered ## Emitted when all colonists are dead/gone — wanderer recovery clock starts. signal storyteller_ghost_state_exited ## Emitted when a wanderer joins and the colony is alive again. # Phase 16 — Save/load. signal save_started(slot: StringName) ## Emitted by SaveSystem.write_save before file IO. signal save_finished(slot: StringName, ok: bool) ## Emitted after file IO; ok=false on write failure. signal load_started(slot: StringName) ## Emitted by SaveSystem.apply_save before clear_all. signal load_finished(slot: StringName, ok: bool, real_seconds_away: int) ## Emitted after respawn; real_seconds_away drives the "you've been away X" toast. # Phase 17 — Touch UX completion. signal pawn_selected(pawn) ## Emitted when Selection picks a pawn — opens PawnDetailPanel. signal pawn_deselected ## Emitted when Selection clears — closes PawnDetailPanel. signal pawn_priority_changed(pawn, category: StringName, level: int) ## Emitted when priority matrix updates a cell. signal alert_added(severity: StringName, text: String, focus_tile: Vector2i) ## Emitted by gameplay subsystems to surface a player notice. severity = info | warn | danger. signal request_wolf_spawn(count: int) ## Phase 15 EventCatalog → WolfSpawner. Decouples threat-event effects from spawner. signal day_ended(summary: Dictionary) ## Emitted by Clock at dusk→night boundary; carries the end-of-day recap dict. # Phase 18 — Alert wiring (dangling signals surfaced to AlertsLog). signal no_stockpile_accepts(item_type: StringName, tile: Vector2i) ## Emitted by HaulingProvider when an item needs haul but no stockpile accepts it (rate-limited per item_type). signal bill_blocked(recipe_label: String, reason: StringName, focus_tile: Vector2i) ## Emitted by CraftingProvider when a bill cannot proceed. reason: missing_ingredient | skill_too_low | no_workbench.