๐ฅ Soulforge
Living design document. The (beta) Character Creator page shipped in TheHowlingWhispers v4.0.0. This doc is the canonical reference for its sections, the 36-field payload, the live age-gate (simplified in Aether v1.0.10), and the API surface. Updated for 4.2.0: added ยง12 "AI Assistant" (Codex โ character-picked voice, `{reply, patch}` JSON, per-field merge, wholesome filter for minor voices). Updated for 4.1.2 to reflect the simplified age gate (ยง8) and the expanded /api/characters endpoints (ยง10).
- ยง1. Vision & Goals
- ยง2. Comparison with workshop.html
- ยง3. Form Structure (9 Sections)
- ยง4. Species Registry (Categorized)
- ยง5. Breeds (Per-Species Sub-Lists)
- ยง6. Body Functions
- ยง7. Persona Schema (11 Fields)
- ยง8. Age Gate Integration
- ยง9. UI/UX (Two-Column Layout)
- ยง10. API Surface
- ยง11. Implementation Plan (4.0.0)
- A. Glossary
- B. Open Questions
- C. References
ยง1. Vision & Goals
The (beta) Character Creator is a streamlined, guided path for building characters. It is a sibling page to the existing /workshop.html Workshop editor โ the power-user version โ but optimized for new users, common archetypes, and the Life Sim's body-stat + age-gate systems.
Three goals:
- Lower the barrier to entry. A new user can have a working character in under 3 minutes, without reading docs.
- First-class species & age awareness. Species and age are first-class fields with a real-time age-gate indicator, so the user understands the safety boundary before publishing.
- First-class body function baselines. The character ships with realistic stamina / food / drink baselines, decay rates, and a "body function profile" preset that maps to the Life Sim's per-stat multiplier.
Compatibility promise: the (beta) creator saves to the same characters table as the Workshop editor. Both pages can edit any character; switching between them is frictionless.
ยง2. Comparison with workshop.html
| Aspect | workshop.html (existing) | character-creator-beta.html (new) |
|---|---|---|
| Audience | Power users; existing character authors | New users; quick creation |
| Form layout | Single long form with all fields visible | Tabbed sections with progressive disclosure |
| Species support | Free-text in persona | Dropdown from registry, with breeds |
| Age field | None (implicit in persona) | First-class field with live age-gate indicator |
| Body function baselines | None | Sliders + species-derived defaults + profile presets |
| Age gate | Server-side, invisible to user | Live on-screen indicator with reason |
| JSON import/export | Yes | Yes (with the new schema) |
| Lyra wizard handoff | None | Lyra can pre-fill the form and hand off to the user for review |
| Storage | characters table | characters table (same) |
ยง3. Form Structure (9 Sections)
The form is two-column: inputs on the left, live preview on the right. Sections are tabbed so the user is never overwhelmed.
ยง3.1 โ Identity
- Name (text, required, 1-40 chars)
- Pronouns (dropdown: she/her, he/him, they/them, it/its, custom)
- Avatar color (color picker, with deterministic fallback for users who don't pick)
- Short description (textarea, 1-2 sentences โ shown in The Lobby card)
ยง3.2 โ Species & Breed
- Species category (auto-browse the categorized registry; user can also search)
- Species (dropdown populated from the selected category)
- Breed (dropdown, populated based on species โ or "N/A" if species has no breeds)
- Real-world notice (auto-shown if species is flagged real-world: "๐บ This is a real-world species. Age gate: hard 18+.")
ยง3.3 โ Age & Maturity
- Age (number input, or "ageless" toggle)
- Age category (dropdown: young adult, adult, middle-aged, elder, ancient โ auto-suggested from age)
- Apparent age (number input, optional โ for shapeshifter cases; the gate uses the lower of age and apparent age)
- ๐ข/๐ก/๐ด Live age-gate indicator (see ยง8)
ยง3.4 โ Biological
- Height (number + unit toggle: cm/in)
- Weight (number + unit toggle: kg/lb)
- Build (dropdown: slim, slender, athletic, average, stocky, muscular, heavyset, rotund)
- Exterior (dropdown, species-dependent โ "skin", "scales", "fur", "feathers", "chitin", "energy")
- Eye color (text or color picker)
- Distinguishing features (textarea)
ยง3.5 โ Body Functions (Life Sim linkage)
- Baseline stamina (slider 0-100, default from species registry)
- Baseline food (slider 0-100, default from species registry)
- Baseline drink (slider 0-100, default from species registry)
- Decay rates (auto-filled from species; manual override checkbox to edit)
- Body function profile (dropdown preset: Athletic, Sedentary, Recovering, Beast, Divine โ applies a multiplier to all baselines)
ยง3.6 โ Persona
- Personality traits (multi-select chips: confident, shy, sarcastic, warm, cold, playful, serious, mysterious, flirtatious, stoic, anxious, bold)
- Speaking style (dropdown: formal, casual, poetic, terse, flowery, archaic, modern, broken, + custom)
- Likes (chip list โ also referenced by the Life Sim persona-aware scoring)
- Dislikes (chip list)
- Fears (textarea)
- Goals & motivations (textarea)
- Taboos (textarea โ also referenced by the age-gate pattern matcher)
- Backstory (textarea, large, up to 4000 chars)
- Scenario (textarea)
- Greeting (textarea โ first message when a user enters a room with this character)
- Example dialogue (textarea, 1-3 turns of example messages)
ยง3.7 โ Voice & Style
- Action color (color picker โ color used for
*action*text) - Thought color (color picker โ for
(thought)text) - Speech color (color picker โ for
"speech"text) - Emoji signature (single emoji shown next to the character's name in chat, e.g., ๐ for Peony)
ยง3.8 โ Visibility & Tags
- Visibility (radio: Public, Unlisted, Private, Hidden)
- Tags (chip input โ free-text chips the user adds)
- Category (dropdown: Original, Official, Community, NPC)
ยง3.9 โ Save / Export
- Save as new character (creates a new row, returns to the character card)
- Save as draft (creates the row with
is_hidden = 1so the user can finish later) - Export as JSON (downloads the full character spec, matches the new schema)
- Import from JSON (uploads a JSON file, validates against schema, pre-fills the form)
- Live preview card (right column, always visible โ shows how the character will look in The Lobby)
ยง4. Species Registry (Categorized)
The species registry is the canonical list of species the system knows about. New species are admin-curated; user-created characters pick from this list.
Storage: data/species-registry.json, loaded on server boot. The (beta) creator fetches it via GET /api/species-registry.
Schema
{
"categories": {
"<id>": {
"label": "<display string with emoji>",
"species": ["<species_id>", ...]
},
...
},
"species": {
"<species_id>": {
"display": "<display string with emoji>",
"category": "<category id>",
"real_world": true | false,
"maturity_age": <number>,
"default_age": <number | null>, // suggested default for new characters
"default_ageless": true | false, // if true, age defaults to "ageless"
"breeds": ["<breed name>", ...] | [],
"default_body": { "stamina": 0-100, "food": 0-100, "drink": 0-100 },
"decay_multiplier": { "stamina": 0-2, "food": 0-2, "drink": 0-2 },
"exterior_options": ["skin", "scales", "fur", ...],
"note": "<short lore / age-gate note>"
},
...
}
}
Seed list (small, categorized, 15 species)
| Category | Species | real_world | maturity_age | Note |
|---|---|---|---|---|
| ๐บ Canines | wolf | true | 18 | Real-world. Hard 18+. |
| ๐บ Canines | fox | true | 18 | Real-world. Hard 18+. |
| ๐ฑ Felines | cat | true | 18 | Real-world. Hard 18+. |
| ๐ Equines | horse | true | 18 | Real-world. Hard 18+. |
| ๐ฆ Avians | raven | true | 18 | Real-world. Hard 18+. |
| ๐ฆ Reptiles & Serpents | snake | true | 18 | Real-world. Hard 18+. |
| ๐ง Mythical & Fae | elf | false | 100 | Maturity at ~100. |
| ๐ง Mythical & Fae | fae | false | 80 | Maturity varies; ~80. |
| ๐ง Mythical & Fae | kitsune | false | 50 | Maturity at ~50 (variable by tail count). |
| ๐ฆ Undead & Demonic | vampire | false | 18 | Default 18+; can be ageless. |
| ๐ฆ Undead & Demonic | demon | false | 200 | Maturity at ~200. |
| ๐ง Humans & Humanoids | human | true | 18 | Real-world. Hard 18+. |
| ๐ง Humans & Humanoids | orc | false | 18 | Fictional humanoid. Default 18+. |
| ๐ค Mechanical & Construct | robot | false | 18 | Default ageless. |
| ๐ค Mechanical & Construct | ai | false | 18 | Default ageless. |
Admins add new species via POST /api/admin/species (with required justification text). All additions are logged.
ยง5. Breeds (Per-Species Sub-Lists)
Each species can have 0-N breeds. The breed dropdown is hidden if the species has no breeds. Examples:
| Species | Breeds |
|---|---|
| wolf | Timber Wolf, Arctic Wolf, Dire Wolf, Werewolf |
| fox | Red Fox, Arctic Fox, Fennec Fox, Nine-Tailed Fox |
| cat | Housecat, Tiger, Lion, Panther |
| elf | High Elf, Wood Elf, Dark Elf, Half-Elf |
| kitsune | One-Tail, Three-Tail, Five-Tail, Seven-Tail, Nine-Tail |
| vampire | Nosferatu, Dhampir, Revenant, Classical |
| dragon | Red, Blue, Green, Black, White, Ancient |
| raven | (none) |
| human | (none โ breed is a free-text "ethnicity / culture" field if needed) |
Breeds are pure flavor โ they don't affect the age gate. The species does.
ยง6. Body Functions
The (beta) creator ships body function baselines that map directly to the Life Sim's user_stats row.
Per-species defaults
"wolf": {
"default_body": { "stamina": 95, "food": 90, "drink": 80 },
"decay_multiplier": { "stamina": 0.8, "food": 1.2, "drink": 1.0 }
}
"elf": {
"default_body": { "stamina": 80, "food": 60, "drink": 90 },
"decay_multiplier": { "stamina": 0.7, "food": 0.8, "drink": 1.0 }
}
"robot": {
"default_body": { "stamina": 100, "food": 0, "drink": 0 },
"decay_multiplier": { "stamina": 0.5, "food": 0, "drink": 0 }
}
Robots have food=0 and drink=0 because they don't eat or drink. The Life Sim skips food/drink decay for them.
Body function profile presets
| Preset | Effect |
|---|---|
| Athletic | stamina +20, food +10, drink +10, decay ร0.8 |
| Sedentary | stamina โ10, decay ร1.2 (faster drain) |
| Recovering | stamina baseline 50, all decay ร0.5 (slow drain โ for post-illness / wounded characters) |
| Beast | stamina +30, food +20, drink +20, decay ร0.6 |
| Divine | stamina 100, food 0 (immortal), drink 0 (immortal), decay ร0 (no decay) |
Presets are applied on top of species defaults. The user can fine-tune the sliders after picking a preset.
ยง7. Persona Schema (11 Fields)
Field reference
| # | Field | Type | Required | Notes |
|---|---|---|---|---|
| 1 | personality_traits | string[] | no | Chips. Referenced by AI behavior. |
| 2 | speaking_style | string | no | Free-text or dropdown. |
| 3 | likes | string[] | no | Referenced by the Life Sim persona-aware scoring (1.0+). |
| 4 | dislikes | string[] | no | Soft reference by scoring; reduces score. |
| 5 | fears | text | no | Up to 2000 chars. |
| 6 | goals | text | no | Up to 2000 chars. |
| 7 | taboos | text | no | Up to 2000 chars. Also pattern-matched by the age gate. |
| 8 | backstory | text | no | Up to 4000 chars. |
| 9 | scenario | text | no | Up to 2000 chars. |
| 10 | greeting | text | no | Up to 1000 chars. First message when a user enters a room with this character. |
| 11 | example_dialogue | text | no | Up to 4000 chars. 1-3 turns. |
JSON shape (new column-free fields; everything else lives in characters)
{
"id": 7,
"name": "Peony",
"description": "A succubus who has lived for centuries.",
"persona": "<legacy persona field โ kept for backward compat with workshop.html>",
"scenario": "<legacy>",
"greeting": "<legacy>",
"examples": "<legacy>",
"is_hidden": 0,
"user_id": 1,
"species": "elf",
"breed": "Half-Elf",
"apparent_age": null,
"body_baseline_stamina": 90,
"body_baseline_food": 80,
"body_baseline_drink": 80,
"body_decay_stamina": 1.0,
"body_decay_food": 1.0,
"body_decay_drink": 1.0,
"age_verified": 0,
"intimate_stats_blocked": 0,
"personality_traits": ["confident", "flirtatious", "mysterious"],
"speaking_style": "poetic",
"likes": ["wine", "rare steak", "dark chocolate"],
"dislikes": ["garlic", "small talk"],
"fears": "...",
"goals": "...",
"taboos": "...",
"backstory": "...",
"greeting_long": "...",
"example_dialogue": "...",
"action_color": "#ffb3d9",
"thought_color": "#d4adfc",
"speech_color": "#ffffff",
"emoji_signature": "๐",
"tags": ["succubus", "fictional"]
}
The legacy persona, scenario, greeting, examples fields are preserved for workshop.html compatibility. The (beta) creator writes to the new structured fields; an admin migration can later fold the legacy fields into the new structure if desired.
ยง8. Age Gate Integration
The (beta) creator ships a live age-gate indicator that shows, in real time, whether the user's character passes the gate.
age set, and that age must be โฅ 18. The earlier two-axis gate (real-world species, persona pattern-matcher, apparent_age, elven maturity) is gone. There is no species-maturity lookup, no persona pattern-matcher, and no apparent_age logic. The species registry is still loaded by the main app for body function defaults, breed dropdowns, and decay multipliers in the (beta) creator โ but it does not influence intimacy gating.The indicator
The form calls POST /api/characters/age-gate-check on every change and renders one of two states:
| State | Display | Meaning |
|---|---|---|
| ๐ข ENABLED | "Intimate stats: ENABLED. Age โฅ 18." | Character's stated age is 18 or above. |
| ๐ด BLOCKED | "Intimate stats: BLOCKED. Age must be โฅ 18. To enable, set age โฅ 18." | Character's stated age is below 18, or no age is set. |
Examples (replicating the table from life-sim.html ยง7.5)
| Species | Age | Indicator |
|---|---|---|
| elf | 17 | ๐ด BLOCKED โ Below 18. |
| elf | 120 | ๐ข ENABLED |
| wolf | 15 | ๐ด BLOCKED โ Below 18. |
| wolf | 25 | ๐ข ENABLED |
| dragon | 50 | ๐ข ENABLED (apparent age is ignored; only stated age matters) |
| robot | (ageless) | ๐ด BLOCKED โ Age is required even for ageless species. |
| vampire | 200 | ๐ข ENABLED |
Why this matters
The age gate is currently a server-side black box. Users don't know it exists until they try to use a feature and it doesn't work. The (beta) creator makes the gate transparent from the first interaction. The user understands the safety boundary, understands why their character is blocked or allowed, and knows exactly what to change to switch states.
ยง9. UI/UX (Two-Column Layout)
Layout
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ TOP BAR: ๐ฅ Soulforge โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ TABS: โ โ โ [Identity] [Species] [Age] [Bio] โ LIVE PREVIEW CARD โ โ [Body] [Persona] [Voice] โ โ โ [Visibility] [Save] โ [Lobby card rendering] โ โ โ โ โ FORM FIELDS FOR ACTIVE TAB โ Name, avatar, species, โ โ โ age, tags, description โ โ (auto-save as draft every 30s) โ โ โ โ ๐ข/๐ก/๐ด Age gate โ โ โ โ โ [โ Previous] [Next โ] โ โ โ [๐พ Save as Draft] [โจ Create Character] โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Behavior
- Tab navigation: click a tab, or use the "Next โ" button. Validation runs before allowing "Next" โ if a required field is missing on the current tab, the user is prompted to fix it.
- Auto-save: every 30s, the current state is saved as a draft (with
is_hidden = 1). If the user closes the tab and comes back, the draft is restored. - Live preview: the right column renders a real-time preview of the character as it would appear in The Lobby. Updates as the user types.
- Age-gate indicator: visible in the preview column at all times. Updates in real time.
- Lyra handoff: if the user came from the Lyra wizard, the form is pre-filled. A small banner at the top says "Lyra has suggested a character โ review and save."
- Workshop switch: a button "Open in advanced editor" switches to
/workshop.html?id=<new_id>for the same character (only enabled after first save, since the character needs an ID).
ยง10. API Surface
| Method | Path | Purpose |
|---|---|---|
| GET | /api/species-registry | Returns the full species + categories registry. Used by the (beta) creator's Species & Breed tab for dropdowns and decay-multiplier baselines. The registry does not influence the age gate. |
| POST | /api/characters/age-gate-check | Body: {age} โ {allowed: true|false, reason: "...", state: "enabled"|"block", effective_age: number|null}. The (beta) creator calls this on every change. Updated for v1.0.10: the body only requires age now; the response includes state and effective_age for the UI. |
| POST | /api/characters/draft | Save a draft (auto-save target). Body: full character spec. Returns {id} so subsequent drafts can update the same row. |
| PUT | /api/characters/draft/:id | Update an existing draft. Body: full character spec. |
| POST | /api/characters | Final save (new character). Body: full 36-field beta payload. Sets is_hidden = 0, is_published = 1 (or as specified in the body). Also accepts the legacy 8-field Workshop payload. Existing endpoint, expanded in 4.1.0. |
| PUT | /api/characters/:id | Update an existing character. Body: full 36-field beta payload. Owner-only by default; admin can edit any character. source = 'beta' is set by the (beta) editor. |
| GET | /api/characters/:id/export | Returns the character as a JSON file (full spec, matches the new schema). |
| POST | /api/characters/import | Body: JSON spec โ validates against schema โ pre-fills the form (returns the spec; does not save until the user clicks "Create"). |
ยง11. Implementation Plan (4.0.0)
Phase breakdown
| Step | Scope | Notes |
|---|---|---|
| 1. DB migration | Add 11 columns to characters | Idempotent; safe to re-run. |
| 2. Species registry file | Create data/species-registry.json with 15 seeded species | Server loads on boot; admin endpoints can edit at runtime. |
| 3. Age-gate function | Server-side isIntimateStatsAllowed(character) (already designed in life-sim.html ยง7.5) | Reused from Life Sim design. |
| 4. /api/species-registry endpoint | GET only | Public, no auth. |
| 5. /api/characters/age-gate-check endpoint | POST, public, no auth | Returns the allow/deny + reason. Used by the (beta) creator's live indicator. |
| 6. /api/characters/draft endpoint | POST, auth required | Auto-save target. |
| 7. /api/characters/:id/export + /api/characters/import | GET + POST | JSON round-trip. |
| 8. Admin species endpoints | POST + DELETE, admin only | For future expansion. |
| 9. The (beta) creator page itself | New public/character-creator-beta.html | The 9-section form, two-column layout, live preview, auto-save. |
| 10. Cross-link from workshop.html | "Try the new (beta) creator" button | Discoverability. |
| 11. Cross-link from characters.html | "Create new character" button points to the (beta) creator by default | Discoverability. |
| 12. Cross-link from Lyra wizard | Lyra hands off to the (beta) creator with pre-filled form | End-to-end flow. |
Scope of 4.0.0
Steps 1-7 + step 9 are mandatory for 4.0.0. Steps 8 and 10-12 can be deferred to 4.0.1 (post-launch polish) without blocking the (beta) creator's launch.
Rollback plan
The (beta) creator is purely additive. Rolling back means:
- Revert public/character-creator-beta.html (does not exist pre-4.0.0).
- Revert the 11-column migration is harder โ we'd need to keep the columns but stop writing to them. Easier: just leave the columns and roll back the page.
- The Workshop editor continues to work, since it doesn't use the new fields.
ยง12. AI Assistant (4.2.0)
Added in 4.2.0. The right column of the (beta) Creator has a tab bar: [๐ Preview] [๐ค Codex]. Click Codex to swap the preview card for a chat panel. The assistant helps the user fill in the 36-field form by listening to a natural-language description and emitting a structured JSON patch that the client applies field-by-field.
Voice picker
The user picks a voice from any character they can see: their own (any state) + all official (user_id IS NULL) + all is_published = 1. The selected character's full DB persona drives the assistant's voice. The task overlay is tone-neutral โ the AI is told "a tsundere can be reluctant, a succubus can be teasing, an AI can be terse" and is explicitly forbidden from copying example text from the system prompt.
The 5-layer system prompt
- Persona โ the selected character's full
personafromcharacters.persona, truncated to 1500 chars for very long personas. Loaded server-side percharacter_id. - Task overlay โ tone-neutral instructions: stay in character, the user is describing a NEW character (not you), output JSON shape, patch rules, field schema, species registry. The "stay in character" directive is repeated at the end as a final reminder.
- 36-field schema โ compact table with field name, type, and notes (e.g.
age MUST be >=18). - 24-species summary โ the 9 categories + 24 species from the registry, in compact form.
- Current form state โ the live form values, passed in by the client on every request so the AI knows what's filled and what's empty.
Patch semantics
The assistant returns { "reply": "...", "patch": { "field": "value" } }. The client merges: for each key in patch, if the value is not null and the DOM field exists, the form is updated. Fields not in the patch are preserved. Chip arrays (personality_traits, likes, dislikes, tags) use append semantics โ the AI sends a list of strings to add; existing chips stay. Unknown fields are silently ignored. A per-message snapshot is taken before each patch so the user can click โฉ Revert on any assistant message to restore the pre-patch form state.
Wholesome filter for minor voices
If the assistant's character has age < 18 (e.g. Hirobe Ayumi at age 15, or any user-created minor), the server rewrites patch.age to 18 if the user asked for younger, and strips intimate_stats_blocked: false. The response includes wholesome_filtered: true and the panel shows a โ wholesome filter tag under the assistant's message. Adult voices (Senako, Peony, Codex) get the open filter. No per-character config required โ the character's age column drives the filter automatically.
API
GET /api/codex/charactersโ list voices the user can pick (auth required).POST /api/codex/messageโ send a message (auth required, 60/hr/user rate limit). Body:{ messages, character_id, current_form }. Response:{ reply, patch, applied_fields, character, wholesome_filtered? }.
Session persistence
The transcript (codexMessages) and the selected character (codexCharacterId) are persisted in sessionStorage (thwCodexSession + thwCodexCharacterId). Page reload restores the conversation; closing the tab clears it. The active tab (preview vs codex) is persisted in localStorage (thwCodexTab). This is the first localStorage/sessionStorage use on the (beta) Creator.
Appendix A โ Glossary
| Term | Definition |
|---|---|
| (beta) creator | The new streamlined character creation page, marked (beta) to signal it's the new path but not the only one. |
| Species registry | Admin-curated list of allowed species, loaded from data/species-registry.json. |
| Age gate | Server-side check that prevents intimate content for characters under the species-appropriate maturity age (or 18 for real-world species). |
| Body function profile | Preset that adjusts the character's stamina/food/drink baselines and decay rates (Athletic, Sedentary, etc.). |
| Body function baseline | The starting value of stamina/food/drink for a new character, used as the default when a user_stats row is first created for them in a room. |
| Apparent age | The age the character presents as, distinct from their actual age. Used for shapeshifter / form-changer cases. The gate uses the lower of age and apparent age. |
| Age gate indicator | The live ๐ข/๐ก/๐ด status shown in the (beta) creator's preview column, updated in real time as the user edits. |
| Real-world species | A species that exists in the real world (wolf, cat, human, etc.). Hard 18+ age gate, no exceptions. |
| Lyra handoff | The integration point where the Lyra character-creation wizard (added in 3.7.0) pre-fills the (beta) creator's form for user review. |
Appendix B โ Open Questions
- Body function profile presets. Are "Athletic / Sedentary / Recovering / Beast / Divine" the right set? Or are some too on-the-nose (e.g., "Divine" feels like a power-fantasy hook).
- Apparent age field. Optional in 4.0.0 or required? If optional, the user might publish a dragon character with no apparent_age and bypass the apparent-age override. The fix is server-side: if species is in the registry and maturity_age is high, the server should require apparent_age for high-maturity species.
- Body function decay override. Should the user be able to override the species-derived decay rate? If yes, the manual override is a "power user" feature. If no, all characters of a species decay the same. Lean toward yes with a clear "advanced" toggle.
- Hidden characters in the registry. If a character is hidden (
is_hidden = 1), does it appear in The Lobby or the (beta) creator's species dropdown? The species itself should still appear (it's a public list); only the character instance is hidden. - JSON import validation. Strict or lenient? Strict prevents malformed imports but is annoying for power users. Lean toward strict with a clear error message pointing to the exact field that failed.
- Workshop โ (beta) creator sync. If a user edits the same character in both pages, who wins on conflict? Last-write-wins is simple. Versioning is safer. Lean toward last-write-wins with a "last modified by <page>" indicator.
Appendix C โ References
- Life Sim Design Document โ ยง3 (Data Model) defines the
user_statsrow that the (beta) creator's body baselines feed into. ยง7.5 defines the age gate that the (beta) creator's live indicator reflects. - Workshop editor โ
/workshop.html. The (beta) creator is a streamlined alternative; both save to the same table. - Lyra wizard โ added in 3.7.0. Pre-fills the (beta) creator's form via the handoff integration.
- The Lobby โ
/characters.html. The (beta) creator's "Create new character" button is the default entry point from The Lobby. - AGENTS.md โ versioning rules, process management (thw), deployment notes.