Files
TheriapolisV3/Theriapolis.Godot/Scenes/Wizard.tscn
T
Christopher Wiebe ee5439285c M6.1: Character creation wizard foundation (.tscn + Resource-based draft)
Pivots from M5's code-built UI to the editor-authorable .tscn pattern
recommended in GODOT_PORTING_GUIDE.md, after a session of fighting
Godot idioms with code-only layout. Default theme only; the parchment
Theme lands last per the guide's §12 build order so layout bugs surface
as layout bugs, not theming bugs.

GODOT_PORTING_GUIDE.md:
  Authored by Claude Design as the canonical port reference. Maps the
  React prototype's structure onto Godot 4.6 with concrete code sketches
  and a build-order recommendation. Drove the M6 architecture.

Fonts/:
  Cormorant Garamond (Medium + MediumItalic) and Crimson Pro (Regular +
  Italic + SemiBold) under OFL — the React prototype's serif-display
  and serif-body families. Not yet wired through CodexTheme.Build()
  because theming is deferred; CodexTheme.LoadFontFromFonts already
  picks them up automatically when the Theme pass lands.

Scenes/Wizard.tscn + Wizard.cs:
  Wizard shell per guide §4: codex-header (title + folio counter) +
  Stepper + Page (StepHost + Aside) + NavBar (Back / validation / Next).
  All node lookups via unique-name (%) syntax; layout authored as a
  scene file you can open in the editor. Step lifecycle drives the
  Aside via signal binding. Stepper logic mirrors app.jsx — locked
  iff some EARLIER step is unsatisfied; "type not yet implemented"
  doesn't lock.

Scenes/Aside.tscn + Aside.cs:
  Right-rail summary per guide §10. Single Refresh() rebuild on
  CharacterDraft.Changed; cheap enough not to bother with partial
  updates. Width 320 (was 380 before the layout overflow fix).

Scenes/Steps/IStep.cs + StepClade.cs:
  Per-step Bind(draft) + Validate() contract. StepClade renders the
  3-column clade card grid; click commits via CharacterDraft.Patch
  which triggers the Resource.Changed signal that Aside and Wizard
  both subscribe to.

UI/CharacterDraft.cs:
  Resource (not Node) per guide §2.1. Mirrors app.jsx's `state` shape
  exactly. Patch(dictionary) emits the inherited Resource.Changed
  signal — listeners use `draft.Changed += handler` regardless of
  which field changed. CodexContent provides lazy-loaded immutable
  content tables (Clades, Species, Classes, Subclasses, Backgrounds).

Main.{cs,tscn}: Node → Control
  When Main was a Node, Control children couldn't anchor to a real
  parent rect — they sat at (0,0) at intrinsic min size. With wide
  step content (3-column 200-px-card grid), the Wizard's min size
  pushed the navbar beyond the viewport's right edge, hiding the Next
  button on smaller windowed viewports. Making Main a full-rect-
  anchored Control gives child scenes a proper rect to lay out in.

UI/Widgets/CodexStepper.cs:
  Anchored the inner vbox to fill the button rect. Without this, the
  vbox sat at the button's top-left at intrinsic size and labels
  rendered in the corner — visible as the active-step label being
  off-center from the highlight bar.

Verified at 1152x720 windowed and (separately) at fullscreen:
  - 3-column card grid fits inside Wrap margins + Aside without
    horizontal overflow
  - Stepper labels centered under their highlight bars
  - Next button visible after clade selection; future steps switch
    to "coming soon" placeholder when clicked
  - Aside summary fills in CLADE block on selection

Closes M6.1.  Next per guide §12 build order: M6.2 — StepStats with
drag-drop (highest-risk piece, de-risk before easy steps).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 19:35:03 -07:00

88 lines
2.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[gd_scene load_steps=4 format=3 uid="uid://wizard6m6v1"]
[ext_resource type="Script" path="res://Scenes/Wizard.cs" id="1_wizard"]
[ext_resource type="Script" path="res://UI/Widgets/CodexStepper.cs" id="2_stepper"]
[ext_resource type="PackedScene" path="res://Scenes/Aside.tscn" id="3_aside"]
[node name="Wizard" type="Control"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource("1_wizard")
[node name="Wrap" type="MarginContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
theme_override_constants/margin_left = 36
theme_override_constants/margin_right = 36
theme_override_constants/margin_top = 16
theme_override_constants/margin_bottom = 16
[node name="Layout" type="VBoxContainer" parent="Wrap"]
[node name="Header" type="HBoxContainer" parent="Wrap/Layout"]
theme_override_constants/separation = 24
[node name="TitleCol" type="VBoxContainer" parent="Wrap/Layout/Header"]
size_flags_horizontal = 3
[node name="Title" type="Label" parent="Wrap/Layout/Header/TitleCol"]
text = "THERIAPOLIS · CODEX OF BECOMING"
[node name="FolioLabel" type="Label" parent="Wrap/Layout/Header/TitleCol"]
unique_name_in_owner = true
text = "Folio I of VIII — Clade"
[node name="MetaLabel" type="Label" parent="Wrap/Layout/Header"]
text = "PORT/GODOT · M6"
[node name="Stepper" type="HBoxContainer" parent="Wrap/Layout"]
unique_name_in_owner = true
size_flags_horizontal = 3
script = ExtResource("2_stepper")
[node name="Page" type="HBoxContainer" parent="Wrap/Layout"]
size_flags_vertical = 3
[node name="PageMain" type="MarginContainer" parent="Wrap/Layout/Page"]
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/margin_left = 12
theme_override_constants/margin_right = 28
theme_override_constants/margin_top = 16
theme_override_constants/margin_bottom = 16
[node name="Scroll" type="ScrollContainer" parent="Wrap/Layout/Page/PageMain"]
size_flags_horizontal = 3
size_flags_vertical = 3
horizontal_scroll_mode = 0
[node name="StepHost" type="VBoxContainer" parent="Wrap/Layout/Page/PageMain/Scroll"]
unique_name_in_owner = true
size_flags_horizontal = 3
[node name="Aside" parent="Wrap/Layout/Page" instance=ExtResource("3_aside")]
[node name="NavBar" type="HBoxContainer" parent="Wrap/Layout"]
theme_override_constants/separation = 24
[node name="BackButton" type="Button" parent="Wrap/Layout/NavBar"]
unique_name_in_owner = true
text = "← Back"
[node name="Spacer" type="Control" parent="Wrap/Layout/NavBar"]
size_flags_horizontal = 3
[node name="ValidationLabel" type="Label" parent="Wrap/Layout/NavBar"]
unique_name_in_owner = true
text = ""
[node name="NavProgress" type="Label" parent="Wrap/Layout/NavBar"]
unique_name_in_owner = true
text = "1 / 8"
[node name="NextButton" type="Button" parent="Wrap/Layout/NavBar"]
unique_name_in_owner = true
text = "Next "