Files
Christopher Wiebe b451f83174 Initial commit: Theriapolis baseline at port/godot branch point
Captures the pre-Godot-port state of the codebase. This is the rollback
anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md).
All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 20:40:51 -07:00

5.5 KiB
Raw Permalink Blame History

Character Creation — Design Intent

This document captures the originally-planned design for the character creation flow, extracted verbatim from the Phase 5 implementation plan (theriapolis-rpg-implementation-plan-phase5.md §4.2). The current shipping implementation deviates from it in one significant way (collapsed to a single screen instead of a multi-step wizard) — both forms are valid; Design is free to redesign in either direction.

From the Phase 5 plan, §4.2 (verbatim):

4.2 Character creation

Screen flow (single Myra panel, multi-step):

  1. Clade. Picker of 7 cards: Canidae / Felidae / Mustelidae / Ursidae / Cervidae / Bovidae / Leporidae. Each shows ability mods + 1-line trait summary.
  2. Species. Filtered to the selected clade. Shows size, ability mods, defining trait.
  3. Class. All 8. Shows hit die, primary ability, level-1 feature names. Recommends species/class fits (informational only — no restrictions).
  4. Background. All 12. Skill proficiencies + tool proficiencies + feature text. Mechanical effects of features are stubbed for Phase 5.
  5. Stats. Two methods, player choice:
    • Standard array: 15, 14, 13, 12, 10, 8 (assignable). Default.
    • Roll 4d6 drop lowest ×6, assign. Each Reroll press derives a fresh seed:
      statRollSeed = worldSeed ^ RNG_STAT_ROLL ^ msSinceGameStart
      
      msSinceGameStart is wall-clock ms since the process started. CharacterBuilder.RollAbilityScores accepts an ulong? msOverride = null parameter; when non-null, that value is used in place of the live ms snapshot. Tests use the override; the game does not. This gives true non-reproducibility across plays, reproducibility within tests, and worldseed-anchored variation.
  6. Skills. Class lists skillsChoose and skillOptions. Player picks N from the offered list (in addition to background's two free).
  7. Name + confirm. Default "Wanderer". On confirm: CharacterBuilder produces a Character, ActorManager.SpawnPlayer is called with that character attached.

Validation: every step's Next button is disabled until the field is valid. CharacterBuilder.TryBuild(out string error) is the single canonical check.

What shipped vs. what was planned

The Phase 5 M2 implementation collapsed the 7-step wizard into a single panel with all selectors visible at once because:

  • Defaults are sensible enough that pressing Confirm immediately produces a working character — no step is strictly required.
  • All inputs are independent (changing class doesn't invalidate clade), so a wizard doesn't actually serialize anything.
  • A single screen is faster to ship and easier to test in M2.

The data model and validation already support either presentation. A multi-step wizard with progressive disclosure (per the original plan) is a fully valid redesign target. So is a denser single-screen layout with better visual hierarchy. So is a hybrid (e.g. two screens: identity, then mechanics).

Constraints (don't redesign these out)

  • Stats seeding rule — the formula statRollSeed = worldSeed ^ RNG_STAT_ROLL ^ msSinceGameStart is locked. Each Reroll press must produce a new outcome (player rerolls for a better roll; we deliberately allow this rather than name-locking). Tests pin the seed via an override parameter.
  • Validation is canonical via CharacterBuilder.Validate(out string error) — UI displays whatever message the builder produces; UI does not invent its own validation rules.
  • Skill count is class-drivenClassDef.SkillsChoose says how many skills the player picks from ClassDef.SkillOptions. Background skills are added automatically and don't count toward this quota.
  • Stats are entered as a 6-value block and assigned to abilities — whether via Standard Array drag/click assignment or a 4d6 roll, the underlying data is six integers in (STR, DEX, CON, INT, WIS, CHA) order. Clade and species mods are applied AFTER assignment (in the builder), so the screen shows both the base value and the post-mod final.
  • Name field is required and free-text. Default "Wanderer". No length cap enforced beyond Myra's TextBox default.

Out of scope for this design pass

  • Hybrid characters (two parent clades). The data layer doesn't support them yet (Character.Clade is a single ref) and they're explicitly Phase 6.
  • Subclass selection at character creation. The data is loaded but Phase 5 defers all subclass mechanics to Phase 5.5+.
  • Backstory / personality fields beyond the suggested-personality string on each background.
  • Save slot picker (separate flow — SaveLoadScreen).
  • Multiplayer / co-op character creation.

What "good" looks like

A redesign that:

  • Keeps "press Confirm immediately and get a working character" working — defaults are part of the contract.
  • Surfaces clade traits, species traits, class level-1 features, and background features at the moment of selection (not buried two clicks away).
  • Communicates the relationship between clade ability mods and species ability mods clearly (additive — both apply).
  • Makes the difference between Standard Array and 4d6 rolling visually obvious so players don't accidentally lock in random rolls.
  • Gives the rolled-stats path a "show previous roll for comparison" affordance.
  • Shows the starting kit (weapons, armor, gear from ClassDef.StartingKit) before the player commits.