using Godot; using Theriapolis.Core.Persistence; using Theriapolis.Core.Rules.Character; using Theriapolis.Core.World.Generation; namespace Theriapolis.GodotHost; /// /// Autoload singleton. Holds the cross-scene state that outlives any /// single screen: the world seed and (post-worldgen) WorldGenContext, /// the pending character from the M6 wizard hand-off, and the pending /// save snapshot from the SaveLoadScreen load hand-off. /// /// Per port-plan §M7 §4.3: TitleScreen + Wizard + SaveLoadScreen write /// pending fields; WorldGenProgressScreen + PlayScreen consume them and /// clear them. /// /// Registered in project.godot under [autoload]; reachable /// from any scene via . /// public partial class GameSession : Node { /// World seed for the next worldgen run. Set by TitleScreen /// (new game) or by SaveLoadScreen (from the loaded header). public ulong Seed { get; set; } /// Set by WorldGenProgressScreen on completion; consumed by /// PlayScreen during _Ready. public WorldGenContext? Ctx { get; set; } /// Set by the Wizard hand-off (M6 → M7.1). PlayScreen /// attaches this to the spawned player actor and clears the field. public Character? PendingCharacter { get; set; } public string PendingName { get; set; } = "Wanderer"; /// Set by SaveLoadScreen when the player picks a slot. /// PlayScreen consumes via ApplyRestoredBody in _Ready. public SaveBody? PendingRestore { get; set; } public SaveHeader? PendingHeader { get; set; } /// Convenience accessor — any node can grab the session via /// GameSession.From(this) without hard-coding the autoload path. public static GameSession From(Node anyNode) => anyNode.GetNode("/root/GameSession"); /// Drop the per-run pending fields. Called on quit-to-title /// so a fresh "New Character" run doesn't see stale handoff data. public void ClearPending() { PendingCharacter = null; PendingName = "Wanderer"; PendingRestore = null; PendingHeader = null; } }