One creature in one Decentraland World. Every visible property of its body — its size, its dance, its plaque — was made by somebody else.
And presence is scarce. Decentraland worlds are venues — wonderful when full, dead when empty, which is almost always.
Someone opens Decentraland on their phone at 2am because they can't sleep. The world they pick is a beautiful, empty room. They look around for eleven seconds and close the app.
This is not a content problem or a graphics problem. It is a scheduling problem, and it is the platform's own retention problem stated plainly: there is no reason to open a venue twice.
Source: specs/spec.md — the problem statement this project was scoped against.
Needs a crowd to show up at a fixed hour, in a fixed timezone.
Needs a paid human awake at 2am, and stops the moment the money does.
Needs somebody on the other end to answer. An empty room has nobody.
All three fail identically: they require other people to be online at the same moment as you — exactly the thing an empty world cannot supply.
Mochi is a giant pastel blob co-parented by every visitor. Feed it and it is physically bigger from then on — for everybody, forever, whether or not you are still online.
Server-authoritative. The scene owns no state, keeps no counter and has no delete verb — nothing anyone contributes can be taken back out.
Two people who never meet still act on each other.
Real constants from src/config.ts. The plaque string is the one the scene prints.
The blob is bigger because people fed it. Not a number beside it — the actual body. Hunger decays over 36 h to a floor of 0.15, so an untended Mochi looks untended, and can never starve.
Each move was taught by one named person. When Mochi performs, it replays the whole chain in order, crediting every move, beside ghost dancers wearing those people's real wearables.
Deliberately coarse. “3h ago” carries the feeling that somebody was here and has since gone; “2h 47m ago” reads like a log file and carries nothing.
On your next arrival, Mochi names the person whose act followed yours. It is the one message in the whole protocol that is never broadcast — it is addressed to a single returning visitor.
Naming note: Kito and Rue are this repo's test-fixture wallets, shown here as the literal string format. They are not real carers — see slide 11 for the real count.
Drawn from the shipped UI source (src/ui/hud.tsx, emote-picker.tsx, plaque.ts) — these are illustrations, not captures. The World is live — walk into it
lastState survives a disconnect on purpose, and no error notice is shown — it would only mark a gap the visitor cannot act on.
Zero imported GLB/GLTF. 26 Tween + 9 TweenSequence, zero Animator.
protocol.ts has zero imports — both sides import the same file, so client and server cannot disagree about what a message is.
Rate limits per wallet per 60s — feed 4 · teach 2 · pet 10 · stamp 2.
Guests render everything and are refused writes.
append-only · teacher_name NOT NULL · no delete verb exists
It is computed from a timestamp, so there is no cron, and the value is correct after any amount of downtime.
FEED is the bowl, TEACH is the stage, PET is a hold on the body, STAMP is a tap on the totem. Device testing found a bottom thumb arc sitting on the client’s own joystick and jump control, so the arc was deleted, not nudged.
Identity comes from the wallet. There is no onboarding modal and no instruction text, because judges arrive as players, not as readers.
Hold-to-pet latches on press and the release is watched globally, so a sliding thumb cannot cancel it. There is no fail state anywhere in the scene — a fat-thumb gesture that can fail is an accessibility defect.
Sized in virtualWidth / virtualHeight, never raw pixels; desktop layout ×3 for mobile per Decentraland's own guidance; wrapped in ScreenInsetArea for notch and home indicator.
One exhaustive test proves no reachable combination of feeding and elapsed time produces a creature that starves. 40,480 decay · 36,432 starvation refuted · 1,150 feeding · 420 no-punishment
Every mesh is a procedural SDK7 primitive. Zero imported GLB/GLTF.
github.com/edycutjong/mochi — read the tests before you believe the numbers.
Four sessions, two wallets, one database file smaller than a favicon. The whole social mechanism fits in 4 KB.
| Criterion | What answers it | Evidence |
|---|---|---|
| Mobile-First Experience tie-break 1 | No buttons at all — four world-space taps, no typing, no tutorial, no fail state. Nothing is drawn over the client’s own controls. | meadow.ts · hud.tsx · controls.ts |
| Social Value | Cooperation without co-presence. Four credited traces — size, chain, plaque, away-line — each naming a specific other person. | chain_move · carer_event |
| Mobile UX & Accessibility | ≥18sp text, ≥4.5:1 contrast, no sound dependency, no timed input, one-handed portrait, notch-safe insets. | ScreenInsetArea · ×3 scale |
| Performance & Optimization | 6.7 MB of a 25 MB budget, under 250 entities of 4,800, zero imported models, dancers degrade 6 → 3 → name tags. | 88–90% (S24 Ultra) |
| Creativity & Originality | A creature whose body is an append-only log of strangers. The away-line is a message that waits for one person to come back. | replay.ts · 12 signatures |
| Retention & Discovery tie-break 2 | The reason to return is authored by somebody else while you were gone, and it is addressed to you by name. | away-line, sent on hello |
| Overall Execution tie-break 3 | 220 tests at 100% coverage, 5-stage CI with CodeQL and gitleaks, one dependency, MIT, honest limitations documented in-repo. | github.com/edycutjong/mochi |
Catching a move performed with the client's own emote wheel is not confirmed on a phone. The 12-tile picker is the shipped fallback, so what is at risk is spontaneity, not the mechanic.
The Decentraland mobile client has no audio event implementation. Nothing in the experience depends on sound.
Correct for one creature and a few hundred carers. It does not shard, and it is not built to.
Seeded rows carry an is_seed flag in the database and are labelled as such. The server refuses guest writes.
Hunger only — not a mood system. A deliberate cut, so the loop stays legible in eight seconds.
One of those seven is me. The other six arrived through the Decentraland community — one of them found the World unprompted — and between them the creature has been fed 86 times and carries a 42-move chain. Four of those people have taught a move that is now permanently credited to them by name: iOSWaifu, ginoct, abnerdune and Blaze Raveneye. Every row is a real wallet performing a real emote. It is more than a test fixture and still less than adoption, and I would rather report seven than dress it up.
A drive with real Decentraland community members is under way — the seven carers above came from it. These remain the numbers I am holding myself to, and they are targets, not results:
Checkpoint 2026-08-31. Whatever the real figure is on submission day, that is the figure the BUIDL will carry.
Open it on your phone, alone, at an odd hour — the condition it was built for. Feed it, teach it one move, close the app. Come back later and read what it says to you.
What continued work buys, in order:
Seasonal chain resets that archive rather than delete — the dance becomes a history with chapters, and nobody's move is ever erased.
A second creature in a second World, so the two can exchange moves — chains that cross communities.
Mobile Discover featuring, if it earns it. This mechanic gets stronger with population — the rare case where distribution improves the product, not just its numbers.
All three are scoped from what already runs today — none of them needs a new platform capability, a new dependency, or a change to the mechanism.
MIT. Tests, CI and the honest-limitations document are all in there.
2:27, captioned. The chain replay at 1:14 is the part that cannot be explained in writing.
Scene, server, tests, CI and this deck. Friendzone Buildathon 2026.
Two people who never meet
still act on each other.