rimlike/autoload/game_state.gd
megaproxy fd6f958344 sprint A cleanup: accessibility, signals, race, debris
G: large_text scales global theme font (14→20 at 1.4×) via new
GameState.get_font_scale + EventBus.settings_changed. reduce_motion
gates ResumeToast fade (HintOverlay already gated).

I: InspectTooltip long-press wired (500ms hold, 12px drift cancel,
tap-to-clear pin). Stale Phase 19 TODO replaced with accurate doc.

H: Pawn.arrived_at_destination now also emitted on
EventBus.pawn_arrived_at_destination; DirtinessSystem subscribes and
bumps indoor traffic dirt (BUMP_INDOOR_TRAFFIC = 0.2). Outdoor-tracked
bump needs Pawn.prev_tile — flagged for Phase 20.

P: CraftingProvider caches ingredient item ref on Job.ingredient_item;
JobRunner._tick_pickup validates is_instance_valid + not being_carried
before the tile scan, cancels cleanly if another pawn grabbed it.

J: rest_provider.gd deleted. Removed @onready + register call from
world.gd, ext_resource + node from world.tscn. Provider count comment
updated to 9.

M: DIRTY_THRESHOLD extracted — cleaning_provider and job_runner now
reference DirtinessSystem.DIRT_DIRTY_THRESHOLD.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:38:14 +01:00

76 lines
2.6 KiB
GDScript

extends Node
## Top-level mutable game state. SaveSystem serializes via save_dict() / apply_dict().
##
## Holds session-wide flags and the "what map are we on" pointer. Per-entity state
## lives on the entities themselves; per-tile state on the TileMap or World.
## See docs/architecture.md.
var current_map_id: StringName = &"slice_temperate_forest"
var session_started_at_unix: int = 0 # for "you've been away X minutes" toast
# Phase 17 — player settings persisted across sessions.
# Auto-pause booleans mirror the SettingsMenu checkboxes.
# Audio floats are 0.0..1.0; default 1.0 (full volume).
# Accessibility stubs wired in a later phase.
var settings: Dictionary = {
"pause_on_threat": true,
"pause_on_wanderer": true,
"pause_on_pawn_down": true,
"pause_on_modal": true,
"show_day_summary": true,
# Phase 19 — onboarding hint system.
# show_hints: master toggle; dismissed_hints: per-hint dismissal log (Array[String]).
"show_hints": true,
"dismissed_hints": [] as Array,
"audio_master": 1.0,
"audio_music": 1.0,
"audio_sfx": 1.0,
"audio_ambient": 1.0,
"accessibility_large_text": false,
"accessibility_reduce_motion": false,
}
func _ready() -> void:
session_started_at_unix = int(Time.get_unix_time_from_system())
## Apply a dictionary of setting values. Unknown keys are silently ignored so
## callers can pass partial dicts (e.g. only the audio block). Each recognised
## key is type-coerced to match the default type in `settings`.
func apply_settings(d: Dictionary) -> void:
for key in d:
if not settings.has(key):
continue
var default_val = settings[key]
if default_val is bool:
settings[key] = bool(d[key])
elif default_val is float:
settings[key] = clampf(float(d[key]), 0.0, 1.0)
else:
settings[key] = d[key]
# Phase 16 expands these into real save round-trip.
func save_dict() -> Dictionary:
return {
"current_map_id": String(current_map_id),
"session_started_at_unix": session_started_at_unix,
"settings": settings.duplicate(),
}
## Returns a font-scale multiplier based on the accessibility_large_text setting.
## 1.0 = normal, 1.4 = large. Multiply any hardcoded font size by this value.
func get_font_scale() -> float:
return 1.4 if bool(settings.get("accessibility_large_text", false)) else 1.0
func apply_dict(d: Dictionary) -> void:
if d.has("current_map_id"):
current_map_id = StringName(d["current_map_id"])
if d.has("session_started_at_unix"):
session_started_at_unix = int(d["session_started_at_unix"])
# Phase 17 — restore settings block; partial saves are fine.
if d.has("settings") and d["settings"] is Dictionary:
apply_settings(d["settings"])