M7.1-7.2: Play-loop hand-off — Wizard → WorldGen → PlayScreen
Lands the M7 plan's first two sub-milestones on port/godot. theriapolis-rpg-implementation-plan-godot-port-m7.md is the design doc (six screens collapse to four scenes + a camera mode, with per-screen behavioural contracts and a six-step sub-milestone breakdown). M7.1 — WorldGenProgressScreen + GameSession autoload + wizard hand-off rewrite. GameSession holds the cross-scene state that outlives any single screen: seed, post-worldgen Ctx, pending character (from the M6 wizard) and pending save snapshot (for M7.3's load path). Wizard forwards StepReview.CharacterConfirmed upward, and TitleScreen swaps to the progress screen instead of just printing the build summary. The progress screen runs the 23-stage pipeline on a background thread, drives a ProgressBar from ctx.ProgressCallback, and writes the full exception trace to user://worldgen_error.log on failure. Escape cancels at the next stage boundary and returns to title. M7.2 — PlayScreen with a walking character. Extracted WorldRenderNode from the M2+M4 WorldView demo so PlayScreen and WorldView mount the same renderer (biome image + polylines + bridges + settlement dots + tactical chunk lifecycle + PanZoomCamera + per-frame layer visibility + line-width counter-scaling). PlayScreen owns the streamer (M7.3 save needs it), composes ContentResolver + ActorManager + WorldClock + AnchorRegistry + PlayerController, spawns the player at the Tier-1 anchor, and wires resident + non-resident NPC spawning from chunk-load events with allegiance-tinted markers. PlayerController ported engine-agnostic to Theriapolis.Godot/Input/. Takes pre-resolved dx/dy/dt/isTactical/isFocused instead of poking MonoGame InputManager + Camera2D, so the arithmetic that advances PlayerActor.Position and WorldClock.InGameSeconds is bit-identical to the MonoGame version — saves round-trip cleanly. Click-to-travel in world-map mode (camera zoom < TacticalRenderZoomMin), WASD step in tactical mode with axis- separated motion + encumbrance + sub-second clock carry. HUD overlay top-left shows HP/AC/seed/tile/biome/view-mode/time. Esc returns to title (M7.4 replaces this with a pause menu). Namespace gotcha: Theriapolis.GodotHost.Input shadows the engine's Godot.Input static class for any file under the GodotHost namespace tree. Files needing keyboard polls (WorldView, PlayScreen) fully qualify as Godot.Input.IsKeyPressed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ namespace Theriapolis.GodotHost.Scenes;
|
||||
/// </summary>
|
||||
public partial class TitleScreen : Control
|
||||
{
|
||||
private const string VersionLabel = "PORT / GODOT · M6.20";
|
||||
private const string VersionLabel = "PORT / GODOT · M7.2";
|
||||
private const string WizardScenePath = "res://Scenes/Wizard.tscn";
|
||||
|
||||
public override void _Ready()
|
||||
@@ -121,10 +121,15 @@ public partial class TitleScreen : Control
|
||||
if (sibling != this) sibling.QueueFree();
|
||||
var wizardNode = packed.Instantiate();
|
||||
parent.AddChild(wizardNode);
|
||||
// The wizard's "← Title" back-button (visible on step 0) emits
|
||||
// BackToTitle; reinstate this title screen when that fires.
|
||||
if (wizardNode is Wizard wizard)
|
||||
{
|
||||
// "← Title" back-button (visible on step 0) emits BackToTitle.
|
||||
wizard.BackToTitle += () => SwapBackToTitle(parent);
|
||||
// M7.1 — Confirm & Begin in StepReview is forwarded by the
|
||||
// wizard as CharacterConfirmed. Stash the built character on
|
||||
// GameSession and hand off to WorldGenProgressScreen.
|
||||
wizard.CharacterConfirmed += draft => SwapToWorldGen(parent, draft);
|
||||
}
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
@@ -134,6 +139,27 @@ public partial class TitleScreen : Control
|
||||
parent.AddChild(new TitleScreen());
|
||||
}
|
||||
|
||||
/// <summary>M7.1 hand-off: snapshot the built character + chosen
|
||||
/// name onto <see cref="GameSession"/>, default the seed (a seed-entry
|
||||
/// UI lands later), and swap to <see cref="WorldGenProgressScreen"/>.</summary>
|
||||
private static void SwapToWorldGen(Node parent, UI.CharacterDraft draft)
|
||||
{
|
||||
var session = GameSession.From(parent);
|
||||
// CharacterAssembler.LastBuilt is populated by StepReview's
|
||||
// OnConfirmPressed → TryBuild call immediately before the
|
||||
// CharacterConfirmed signal fires.
|
||||
session.PendingCharacter = CharacterAssembler.LastBuilt;
|
||||
session.PendingName = string.IsNullOrWhiteSpace(draft.CharacterName)
|
||||
? "Wanderer"
|
||||
: draft.CharacterName;
|
||||
session.Seed = 12345UL; // default for M7; seed-entry UI is M8+.
|
||||
session.PendingRestore = null;
|
||||
session.PendingHeader = null;
|
||||
|
||||
foreach (Node child in parent.GetChildren()) child.QueueFree();
|
||||
parent.AddChild(new WorldGenProgressScreen());
|
||||
}
|
||||
|
||||
private void OnContinue()
|
||||
{
|
||||
// M7 territory — the play-loop screens that consume the persisted
|
||||
|
||||
Reference in New Issue
Block a user