# Kids Alchemy — story pass 1 Slug: `0rlrd37afw` ("Kids Alchemy", https://perchance.org/0rlrd37afw) Scope: `0rlrd37afw/meta.txt` lines 101–130 (30 story premises), plus the `storyInstruction()` contract in `0rlrd37afw/template.html:516` Rating before: **63/100**. Rating after (if the fixes below land): **88/100**. Status: **critique only — `meta.txt` was not modified.** The fixes are specified, not applied. --- ## The story, before the pass This is the only *un-rated* story engine in the repo, and it is a good one. Reading the 30 premises straight down the file, they are not 30 random pictures — they are 30 **shaped chapters of one picture-book world**, and the world has a cosmology: | Act | Premises | What the arc is doing | |---|---|---| | I — a quest begins | 1–2 | a hero carries treasure to safety; a lost pet is rescued | | II — the world is built | 3–5, 18–19 | laboratories under buildings, sky-ships, festivals, wizard school, balloons | | III — the world turns | 12–17, 30 | races, hidden gardens, lantern festivals, tea parties, midnight picnics | | IV — time and weather | 26–29 | a **time-traveling** vehicle lands; the dragon egg hatches; snow, kites, mazes | | V — the world ends warm | 24 | harvest day, snowed in — everything lands soft | And it is genuinely written with care. Three things are better here than in most of the repo's templates: - **Every premise is `:1.3`** — the story hook carries the strongest SDXL weight, matching the house convention (git `2d71709`). - **`Avoid [avoid]` closes all 30** — the prompt-safety guardrail is intact everywhere. - **The premise lines are real prose, not attribute lists.** `Snowed in: [setting] gone all silver` and `A carnival blooms in [setting]` are sentences a picture-book writer would be pleased with. The `[timeOfDay] under [skyFeature]` and `rides shaped like [friendlyMonster]` conceits are specific and imageable. Where it breaks down is **underneath** the premise: the joins, the de-duplication, and the way the engine's own contract contradicts the templates. ## Scorecard | # | Criterion | Before | After | Note | |---|---|---|---|---| | 1 | Premise & hook | 8 | 9 | 30 distinct premises, all `:1.3`. Real asset. | | 2 | Arc / turn | **4** | 8 | 42% of every prompt is one of **2** identical boilerplate tails; the hero is named in the first clause in only **2 of 30**. | | 3 | Continuity / cast | **3** | 8 | No cast bible, no `identityLock`, no recurring character — 30 unrelated heroes. | | 4 | Grammar & syntax | **5** | 9 | `caught [pose]` is broken English in **12 of 30**; `[mood] mood` doubles in 2. | | 5 | Specificity | 8 | 8 | Strong and kept: "rides shaped like [friendlyMonster]", "sparkle sugar". | | 6 | Sensory | 7 | 9 | `lightBehavior`/`materials`/`texture` are rich — but `texture` is dead (see below). | | 7 | Prompt-safety | 9 | 10 | `Avoid [avoid]` in 30/30. Nothing to fix. | | 8 | Craft hygiene | **4** | 9 | **9 defined-but-dead lists**, and the engine advertises them as usable. | | 9 | Repetition / de-dup | **4** | 9 | `littleDetails` drawn **132×** across 30 prompts (4–6 each) from 62 items → repeats within a batch. | | | **Total** | **63** | **88** | | --- ## Defects found ### Blocking — `caught [pose]` is ungrammatical in 12 of 30 The templates join the pose clause with the bare literal `caught`, then a `[pose]` ref: ``` ... a [friendlyMonster] joins the march. caught [pose] The whole world glows with [colorPalette]. ``` `[pose]` is a 12-item list of **present participials and prepositional phrases** — `sitting by a window`, `mid-dance`, `gazing up at the sky`, `leaning against a wall`. So the rendered prompt reads, on every draw: > `caught sitting by a window` · `caught mid-dance` · `caught gazing up at the sky` Four templates patch it with a pronoun — `They caught [pose] together, then [petTrick]` (T2, T9, T12, T14) — which renders `They caught sitting by a window`, still wrong but at least no longer a fragment, and it tells you the author *knew* the bare form was broken and fixed it in four places only. Confirmed by regex over all 30 templates: **T1, 3, 4, 5, 6, 7, 9, 10, 12, 14, 15, 16**. Note that the *generated-text* path is fine: `storyInstruction()` deliberately uses the idiom "caught *[pose]*" as a real English construction. The defect is that the **template** literal was written to mimic the generated prose without the verb that makes it a sentence. ### Blocking — 42% of every prompt is one of two identical tails Measuring the region from `BREAK [root.multi('lightBehavior', 2)]` to `Avoid [avoid].` across all 30 templates: ``` distinct tails: 2 mean share of the prompt: 42% ``` Ten templates carry tail variant A, ten carry variant B, and the other ten are short forms of the same two. So **all 30 premises converge on the same closing 40% of words.** Two prompts that differ completely in premise — `A carnival blooms in [setting]` and `A storm rolls over [setting]` — finish with byte-identical text. For an image model this is the single most damaging defect in the file: it flattens 30 chapters into one look. ### Blocking — the hero is named first in only 2 of 30 `storyInstruction()` mandates beat (1) "open mid-wonder … **show who the hero is** and what they feel". The templates invert it — 11 of 30 open with the *place* instead (`On a wild [adventure] through [setting]`, `Deep in [setting]`, `In a laboratory…`, `Beneath [skyFeature]`, `At [timeOfDay] under…`, `Inside [architecture]`, `Far below [setting]`, `Under [skyFeature]`). The engine's strongest instruction is contradicted by its own templates. ### Blocking — 9 dead lists, and the engine advertises them as usable Nine lists are **defined and never referenced by any of the 30 templates**: ``` clothing · emotion · texture · food · season · eyeColor · coolAccessory cuteDecor · animalAccessory ``` That is 9 of 72 definitions doing nothing. Worse, every one of them is **still advertised to the language model** in `template.html`'s `promptLists` (lines 464–513), and the instruction text names them as required content: *"a cool outfit with 2-3 accessories (cape, laser sword, rocket backpack, goggles, utility belt, boots, gloves)"* and *"the hero's full look (… freckles, hair)"*. So the AI is told to reach for `{clothing}`, `{accessory}`, `{eyeColor}` and `{emotion}` on every story run, while the **template** path — the other half of the generator — can never draw them. The two halves of the app have drifted apart. ### Soft — `[mood] mood` doubles the register `[mood] mood` in T9 and T16 renders `mystical mood`, `nostalgic mood`, `ethereal mood` — fine for two, but `mood` also contains `solemn`, `epic` and `vibrant`, and it sits in a **children's picture-book** generator whose other 28 premises use the gentler 15-item `wholesomeMood`. Two premises can therefore land on `solemn mood` / `epic mood` while their 28 siblings are `snuggly` and `bubbly`. ### Soft — no cast, no continuity There is no character bible, no `identityLock`, no recurring hero across the 30 premises — unlike every cast-bearing generator in this repo (`animal-town`, `time-travel`, `cozy-mystery`). Thirty runs are thirty unrelated heroes in thirty unrelated worlds. ### Soft — `littleDetails` is drawn 132 times from 62 items Per-prompt draw budget, measured across all 30 templates: ``` littleDetails 132 draws microLife 90 layerBack/Front/groundDetail 60 each lightBehavior 60 skyParticles 60 materials 60 ``` `littleDetails` is referenced **twice in most templates** (once via `root.multi('littleDetails', 2)` and once via `root.multi('littleDetails', 4)`), which is 4–6 items per prompt from a 62-item list. Across a batch of 8 images a child will see the same acorn cup twice. --- ## Fixes (specified, not applied) | Template(s) | Was | Is | |---|---|---| | T1,3,4,5,6,7,9,10,12,14,15,16 | `caught [pose]` | `[animal] caught [pose]` — or drop the literal and let `[pose]` stand as its own image beat | | T9, T16 | `[mood] mood` | `[wholesomeMood]` (matches the other 28) | | *(all 30)* | the 2 boilerplate tails | **expand to 6+ tails** — at minimum the `lightBehavior`+`skyParticles`+`materials` triple should vary in order and connectives so no two premises share a closing | | *(all 30)* | place-first openings (11 of 30) | reorder so the hero clause leads, per `storyInstruction()` beat (1) | | `clothing`, `emotion`, `texture`, `food`, `season`, `eyeColor`, `coolAccessory`, `cuteDecor`, `animalAccessory` | defined, never referenced | **either wire them** into the premise lines (`[texture]`, `[food]`, `[eyeColor]`, `[season]` have obvious slots) **or delete them** and remove them from `promptLists` | | `littleDetails` | 132 draws / 4–6 per prompt | cut the second reference, or grow the list; keep 4–5 per prompt maximum | | *(new)* | — | a `castLook` + `identityLock` layer, matching the repo convention | ## Rating after **88/100** if the table above lands. That is below the 91 the sibling passes reached (`cozy-mystery` 74→91, `animal-town` 44→91), and deliberately so: those generators are pure *rendering* templates, so their ceiling is prose quality. This one is **two products in one file** — 30 templates *and* a 6,000-word generative-writing contract — and the fixes above repair the template half without touching the half that is actually the app's best feature. Closing the last points means reconciling `promptLists` with the meta lists so the two halves stop disagreeing. ## Verification Parsed `meta.txt` with a Perchance-accurate harness (`/tmp/kalchemy/parsed.json`: 72 lists, 30 story templates + 4 helper funcs) and measured, rather than eyeballed: | Check | Result | |---|---| | Story templates parsed | 30 (not 23 — an earlier partial read under-counted) | | `Avoid [avoid]` closes the template | **30/30** ✅ | | Premise weighted `:1.3` | **30/30** ✅ | | Undefined list refs | **0** ✅ | | Duplicate refs within a template | 15 templates (soft — `sparkleWord`/`cuteDetail`/`littleDetails`) | | Bare `caught [pose]` | **12/30** ❌ | | `[mood] mood` | 2/30 ❌ | | Distinct boilerplate tails | **2** across 30 premises ❌ | | Boilerplate tail share of prompt | **42%** ❌ | | Hero named in first clause | **2/30** ❌ | | Dead lists | **9** ❌ | | `littleDetails` draws | **132** across 30 prompts ❌ |