2026 10 27 kid creations design - xopherdeep/do-it-for-the-xp GitHub Wiki

Kid creations: beasts and quests the kids make, parents approve โ€” design

Owner brainstorm 2026-10-27. Classified architectural: a new content type (a creation that waits for a parent), a new lane in Approvals, and a new per-kid permission. Board epic: see the plan section at the end.

Why

The family's bestiary is already the kids' art (001โ€“093 are their drawings, scanned by the owner). Kids already make quests for themselves with the Quest Wizard. What they cannot do is make a beast in the app, give it a look, say which chores beat it, or suggest a chore for a sibling or a parent. The owner wants the kids to be co-authors of the game, with the parent still deciding what enters the family's game: a 6-year-old and a 12-year-old can both contribute from their phone, and a parent can say yes or no in ten seconds.

Decisions (owner, 2026-10-27)

The owner chose D1 outright. D2โ€“D4 were the recommended options, accepted with "ok continue"; the board carries them as owner tasks so they can be overturned before the build.

  • D1 Gate: a kid proposes; nothing is live until a Game Master taps Approve (or sends it back with a note). A per-kid setting, off by default, lets a kid make things ("Maker").
  • D2 Look: a kid's beast gets its look from a photo of their drawing (camera or file) or from the beast library (portrait and battle background). An in-app pixel pad is a follow-up, not in this spec.
  • D3 Audience: a kid's suggested quest can be for anyone in the family: self, a sibling, the whole party, or a parent. The Game Master sees the target when approving and may change it.
  • D4 Reward: credit ("Drawn by Ronan" on the beast, "Suggested by Jack" on the quest) plus a little AP when the creation is approved. Never GP: money-valued rewards are shop items (rewards-vs-powers rule).
  • D5 Today's self-quests keep their path. A kid's quest for themselves with a library beast still saves live, as shipped (claims need approval). Only the new things wait: a beast, a quest for someone else, and a quest that uses a beast that is still proposed. One gate per creation, never two.

1. Scope

In:

  • A Beast Maker for kids in the portal: look, name, the chores that beat it, ready. Saves a proposed beast.
  • The Quest Wizard for a Maker kid gains "Who is it for?" (self, a sibling, everyone, a parent) and saves a proposed quest when the target is not themselves or the beast is proposed.
  • A Creations lane in Approvals: approve, send back with a note, or edit in the Game Master's own form.
  • My creations for the kid: what is waiting, what came back with a note (fix and resend), what was approved.
  • The Maker setting per kid in Settings > Party.
  • Credit wherever the beast or quest shows, and the AP pay on approval.
  • Notifications both ways, the approval reminder and the dashboard tile count creations.

Out (follow-ups on the board):

  • A pixel pad; cutting the paper out of a photographed drawing; a HomeTown building for the Maker (the Scriptorium).
  • Proposals from a free kid phone (today's phone-claim channel carries claims only). Creations work on the family device and, once Family Sync part 3 lands, on a Pro kid phone as synced records (section 7).
  • Kids editing or deleting beasts and quests they did not make.

2. Approaches considered

  • A. The proposal lives on the record (chosen): a beast or quest carries a proposal block and is hidden from play until approved. No new store, no copy on approve, and Family Sync already treats __beasts and __achievements as any-writer stores whose hero-key rows carry their own hero, which is exactly what a proposal is.
  • B. A separate creations store that holds drafts until approval, then copies into the bestiary or the quest list. Cleaner lane, but a new synced store (server change), two ids per creation, and a copy step that can half-fail.
  • C. Live at once, Game Master can undo. Fastest for kids; the owner chose the gate instead.

3. The proposal

One shape, shared by beasts and quests, in src/lib/services/creations/creations.ts (pure, jest):

export interface Proposal {
  by: string;                                   // hero id of the maker
  on: string;                                   // ISO, when it was sent
  state: "proposed" | "returned" | "approved";
  note?: string;                                // the Game Master's send-back note
  reviewedBy?: string;
  reviewedOn?: string;
  questId?: string;                             // on a beast: the quest the kid made with it, approved together
}
  • Beast gains proposal?: Proposal and madeBy?: string (kept after approval for the credit; proposal stays too, for history). Achievement already has createdBy; it gains proposal?: Proposal, and a proposed quest is saved with draft: true, so QuestEngine.filterQuests hides it from every hero without a change.
  • isLiveBeast(beast): no proposal, or proposal.state === "approved". Everything that lists family beasts for play or linking takes it: BestiaryService.listBeasts / loadRandomBeast, the quest form's beast pick and useBestiarySelectionStore, the temple room editors, beastLinks, tamedBeasts. The Game Master's Bestiary page shows proposed beasts under a Creations filter, never mixed in.
  • Transitions, all pure and idempotent: propose(record, by, now), approveBeast(beast, reviewer, now), approveQuest(quest, reviewer, now, target) (clears draft, sets the assignee the reviewer chose), returnCreation(record, reviewer, note, now), resend(record, now) (returned โ†’ proposed, keeps the note in history). Approving an already approved record does nothing and pays nothing.
  • Caps: a kid may have 10 creations waiting or returned at once (MAKER_CAP); the Maker says "Ask a Game Master to look at your creations first" past that. A returned creation the kid deletes is gone; the Game Master's history keeps a line.
  • Credit: creditLine(record, users) gives "Drawn by Ronan" for a beast with a picture, "Made by Ronan" for a library look, "Suggested by Jack" for a quest.
  • AP: creationAp(kind) is the AP a wizard quest of size 3 pays for a beast and of size 1 for a quest, from the wizard's reward table (no new numbers). Paid once on approval through recordAPGain({ source: "creation" }), marked on the proposal (paidOn), so a replay cannot pay twice.

4. The Maker setting

FamilySettings.makers: string[] (hero ids allowed to make things; default empty). Family settings are family scope, written by parents only, so a kid phone cannot flip its own flag (a profile field could). Settings > Party gets a "Maker: can make beasts and suggest quests" toggle per kid on the profile row. canMake(heroId, settings) is the one check the portal uses; a Game Master is always a maker (their creations never wait).

5. The kid's side

Entry. The same add menu on the quests page and the calendar that opens the Quest Wizard today gains Draw a beast (shown only to makers). Spoken in the three voices through the copy catalog (copy/catalog/beastMaker.ts), auto-read in the simple voice like the Quest Wizard.

Beast Maker (XpBeastMakerModal.vue, a portal modal like the Quest Wizard; steps and draft rules reuse beastWizard.ts: newBeastDraft, addChore/moveChore/dropChore, beastProblem, beastPatch):

  1. Look โ€” two big tiles: Take a picture of your drawing and Pick one from the library. The photo path is a new BeastPhotoPicker (section 6). The library path is the Quest Wizard's library browse (browseLibrary) with the portrait pick plus the battle background chooser the Game Master's form uses.
  2. Name โ€” "What is it called?"; a Suggest a name button offers three from the library's naming patterns.
  3. Chores โ€” "What chores beat it?": one to five, the same step list control as the Quest Wizard (add, move, drop).
  4. Ready โ€” the card as the family will see it (portrait on its battle background, name, chores, "Drawn by {me}"), a line "A Game Master looks at it first", and Send it. After the fanfare: Make a quest with it opens the Quest Wizard prefilled with this beast; that quest is proposed and linked (proposal.questId), so the pair is approved together.

Quest Wizard for a maker. The "who" step the Game Master sees today opens for a maker kid with four choices: Me, {sibling} (one tile per party member), Everyone, A parent (one tile per Game Master). The difficulty stays clamped as today. buildWizardQuest saves a proposal when the target is not only the maker or the chosen beast is proposed; otherwise today's live path (D5). The ready step's note changes to match: "A Game Master looks at it first" versus today's "a Game Master checks it when you finish".

My creations. The Maker's opening screen lists the kid's creations newest first with a state chip: Waiting, Came back (shows the note; Fix it reopens the Maker with the draft, Send again resends unchanged), In the game (opens the Beast Card or the quest). Delete is a swipe on waiting or returned rows only.

6. A photo of a drawing

src/components/organisms/BeastPhoto/BeastPhotoPicker.vue with its rules in beastPhoto.ts (pure): the file input with accept="image/*" and capture as ClaimPhotoPrompt does, then a square crop the kid drags (a frame over the picture, pinch or buttons to size it; a tap on Fit centres the largest square), then shrink to PORTRAIT_SIDE (512) and compress under PORTRAIT_MAX_BYTES (150 KB) with fitPhoto/nextQuality from claimPhotos.ts, stored as the beast's localImage data URL. Battle, the Beast Card and the bestiary already draw localImage. The Game Master's form (XpAddBeast.vue) gets the same picker as a third look option, since the owner scans the kids' art today.

7. The Game Master's side

Approvals gains a Creations segment (badge = waiting creations). ApprovalCreationRow.vue: portrait, name, "Drawn by Ronan ยท 3 chores" or "Suggested by Jack ยท for Mia ยท size 2 ยท mornings", waited-for line, and three actions:

  • Approve: approveBeast / approveQuest; for a quest a one-tap target chooser first when the kid picked someone else ("For Mia โ€” change?"). Pays the AP, sends the kid creation-approved, writes the history row.
  • Send back: a note sheet (the same one claims use), sends creation-returned with the note.
  • Edit: opens the Game Master's own form (xp-create-update-beast or the quest config) on the record; saving there approves it with the edits ("Approved, with changes" in history).

A beast proposed together with a quest shows as one row ("+ a quest for Mia"); approving takes both, sending back returns both with one note.

Elsewhere: the Bestiary page shows a Creations filter and a "Drawn by" chip; the quest list and calendar show "Suggested by"; the dashboard Approvals tile and approvalReminders count creations; approvalWatch raises creation-waiting for a Game Master the first time a creation sits unseen, with the same quiet rules as claims.

Notifications: three new kinds, creation-waiting (Game Master, links to Approvals > Creations), creation-approved and creation-returned (the kid, link to My creations), with icons in iconOfKind.

8. Family Sync (part 3) alignment

A proposal is a row in __beasts or __achievements made by a hero key: syncScopes must derive the hero id of a beast row from madeBy (and of a quest row from createdBy, as planned). Approval runs on a Game Master device, which may write any row; the AP pay follows the verdict rule of the Family Sync spec section 6 (paid by the device holding the hero's turn, or by the Game Master device taking it for the moment), keyed by proposal.paidOn so it pays once. This spec adds no store, no event kind and no server route. Board #1508 (Family Sync) gets a note to read madeBy.

9. When things go wrong

  • A photo that will not load or shrink: the picker says "That picture didn't work. Try again or pick one from the library"; nothing is saved.
  • Storage full on save: the Maker keeps the draft in memory and says so; the kid can retry.
  • A kid loses the Maker setting while a creation waits: the creation stays in Approvals; only new ones are blocked.
  • The maker's profile is deleted: creations by that hero are returned to the Game Master's history as "maker gone"; approved beasts keep the name in the credit line.
  • Approve on a quest whose target hero was deleted: the chooser opens with the maker preselected.

10. Testing

Jest, pure modules: creations.spec.ts (every transition, idempotent approve, caps, isLiveBeast and the filters that take it, credit lines, creationAp), beastPhoto.spec.ts (crop frame maths, fit, size loop), familySettings (makers normalised, canMake), questWizard.spec.ts additions (the maker who step, when a draft becomes a proposal, D5 unchanged), Notifications.spec.ts kinds and icons, approvalWatch and approvalReminders with creations. Component specs for ApprovalCreationRow and the Approvals segment. One Cypress walk: a maker kid photographs a fixture drawing, names the beast, sends it with a quest for a sibling; the Game Master approves from the Creations lane; the beast shows in the bestiary with "Drawn by", the sibling sees the quest, the maker has the AP.

11. Plan (board epic)

Slices in build order; each is a board task under the epic. Settings and the model first, then the kid's side, the Game Master's side, the credit, the walk.

Slice What Needs
KC1 Proposal model and rules (creations.ts), fields on Beast/Achievement, isLiveBeast through every family-beast list standard
KC2 The Maker setting (FamilySettings.makers, canMake) and the Settings > Party toggle light
KC3 BeastPhotoPicker + beastPhoto.ts (square crop, shrink), also offered on the Game Master's beast form standard
KC4 The Beast Maker modal, its copy catalog, the add-menu entry, Make a quest with it deep
KC5 Quest Wizard: the maker's who step and the proposal save path (D5 kept) standard
KC6 Approvals Creations lane: rows, approve / send back / edit, paired rows, AP pay, history deep
KC7 Notifications, approval watch and reminders, dashboard tile light
KC8 My creations: list, fix it, send again, delete standard
KC9 Credit: Bestiary filter and chip, Beast Card "Drawn by", quest rows "Suggested by" light
KC10 Cypress walk, docs (Roadmap, this spec's follow-ups), Family Sync note on #1508 standard

Owner tasks on the board: confirm D2โ€“D5; the AP amounts (or a Monster Maker look unlock instead); where the Maker lives (the add menu now, a Scriptorium building later); the pixel pad as a follow-up.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ