A preschool sandbox for exploring feelings — built pedagogy first, then the world, in that order and on purpose.
Sound on. Best with a grown-up nearby. Nothing leaves your device.
What this is
Andrej Karpathy gave a model the first paragraph of The Lord of the Rings, a 1M-token budget, and asked for a three.js render. Cara Engelbrecht ran the same shape at a preschool letter-A world, and named what was missing:
“almost no product or pedagogy direction” … “sketchy pedagogy” … “I'm super curious to try with proper product spec and educational guidance.”
This is that try. Same budget, same shape — but the order of work is inverted. The design document (outcomes → evidence → activities) was written before a single line of game code, and the world was chosen last, to serve it.
The load-bearing decision
Recognizing a feeling in a character can be right or wrong, and can be taught. Reporting a feeling in yourself cannot be wrong.
A game that scores a four-year-old's own feeling teaches the single most damaging lesson in emotional learning: that someone else holds the right answer about your insides.
So the two are split — and the split is enforced by code, not by good intentions. The assessment record throws if anything ever tries to attach a correctness mark to a self-report:
if (e.selfReport && 'correct' in e) {
throw new Error(
'A self-report can never be marked correct or incorrect. See DESIGN.md §0.'
);
}
The failure mode this guards against is a future well-meaning change — “let's track whether their self-report matches their behavior” — which would quietly reintroduce the exact lesson the design exists to prevent. Better a crash than a code review.
Backwards design
Written as things you can watch a 3–5 year old do, and authored in a real
backwards-design tool as outcome → criterion → assignment triangles, where
the criterion is the evidence.
| # | Outcome | Mechanic | Assessed? |
|---|---|---|---|
| LO1 | Names five feelings by face and by word: happy, sad, angry, scared, calm | Bring the Feeling | Yes — about characters |
| LO2 | Reads a feeling from the face of a character they have never met | The Feelings Lens (held-back characters) | Yes — transfer check |
| LO3 | Says what happened that made a character feel the way they feel | What Happened Here | Yes — plausible, not single-answer |
| LO4 | Says how they themselves feel, in words they choose | My Cove | Never. Not assessable. |
| LO5 | Names one thing that helps a big feeling get smaller | Make the Storm Smaller | Yes — about characters |
| LO6 | Accepts that two people can feel differently about the same thing | Structural — every event has two disagreeing witnesses | Yes — structural |
Deliberately not outcomes: reading emotion words as text (the audience is pre-literate); “managing” or suppressing emotion; empathy as performance (“say sorry”), which at this age trains compliance rather than empathy.
Constraints
Verification
Karpathy's closing point was that a model building a world can't perceive it. Taking screenshots caught real bugs here — two of the five faces were mutually unreadable, and a crash left a blank screen a child could never recover from.
But screenshots cannot catch “on the 300th run it told a child their feeling was wrong.” So the invariants are machine-checked over many programmatic rounds:
Wrong answers never produce “no”, “wrong”, or “try again”.
Both directions: scoring a self-report, and recording LO4 unflagged.
Self-reports never appear in any assessable roll-up.
No strategy, applied any number of times, reaches zero.
Every event has exactly two, feeling differently, each with a “because”.
LO2 characters never appear in teaching activities.
Verified to catch
violations, by deliberately introducing two. A test that cannot fail is not a test.
Open the game and run await __audit(15) in the console.
Sibling
A 2nd-grade sandbox for feedback loops. Four machines, four outcomes — and a recorded prediction about what backwards design would reach that free association would not.
Honesty