2026 10 27 kid creations design - xopherdeep/do-it-for-the-xp GitHub Wiki
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.
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.
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.
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.
-
A. The proposal lives on the record (chosen): a beast or quest carries a
proposalblock and is hidden from play until approved. No new store, no copy on approve, and Family Sync already treats__beastsand__achievementsas 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.
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
}-
Beastgainsproposal?: ProposalandmadeBy?: string(kept after approval for the credit;proposalstays too, for history).Achievementalready hascreatedBy; it gainsproposal?: Proposal, and a proposed quest is saved withdraft: true, soQuestEngine.filterQuestshides it from every hero without a change. -
isLiveBeast(beast): no proposal, orproposal.state === "approved". Everything that lists family beasts for play or linking takes it:BestiaryService.listBeasts/loadRandomBeast, the quest form's beast pick anduseBestiarySelectionStore, 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)(clearsdraft, 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 throughrecordAPGain({ source: "creation" }), marked on the proposal (paidOn), so a replay cannot pay twice.
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).
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):
-
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. - Name โ "What is it called?"; a Suggest a name button offers three from the library's naming patterns.
- Chores โ "What chores beat it?": one to five, the same step list control as the Quest Wizard (add, move, drop).
-
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.
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.
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 kidcreation-approved, writes the history row. -
Send back: a note sheet (the same one claims use), sends
creation-returnedwith the note. -
Edit: opens the Game Master's own form (
xp-create-update-beastor 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.
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.
- 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.
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.
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.