Monkegotchi — Plan
A Tamagotchi-style virtual pet for the MonkeDAO community, with an optional AI agent companion via Telegram. Mobile-first, mass-market for the pet, motivated users for the agent.
Context
Build a Tamagotchi-style virtual pet ("Monkegotchi") for the MonkeDAO community. The pet is the visible vessel for a Telegram-based AI agent ("OpenClaw") the user is also building. Two surfaces: a Telegram Mini App + a standalone mobile-first web page. Audience is mass-market for the pet, motivated users for the optional agent companion.
Goal of v1: ship a hatchable, evolving, agent-coupled pet that any user can care for, with optional SMB-trait personalization for holders. Reuse OSS where it accelerates us; build the state machine ourselves since it's small (~300–600 LOC TS).
Product shape — two halves, three entry points
Monkegotchi is two complementary products that share one identity + state layer. Users enter from any of three doors and converge to the same end state:
┌─ Anonymous Web Pet ─┐
│ (anon server row) │
└────────┬────────────┘
│ opt-in: claim with email or TG login
▼
┌─────────────────────┐
│ Linked Pet │
│ (no agent) │
└────────┬────────────┘
│ opt-in: BotFather wizard
▼
┌─────────────────────┐
│ Pet + Agent │ ◄── /hatch from
│ (full experience) │ agent-first user
└─────────────────────┘
▲
│ opt-in: hatch a pet
┌─────────────────────┐
│ Agent only │ ◄── existing multi-user-openclaw user
└─────────────────────┘
- Pet half — mini-app + threshold worker + D1 + image-gen. Has standalone value as a web game.
- Agent half — existing multi-user-openclaw infra + a new
monkegotchi-skill. Has standalone value as a personal AI agent. - Glue — a single D1 row per pet keyed by an owner id:
anon:{device_uuid}from first hatch, re-keyed totg:{user_id}(or email) on claim. Claiming moves no state across the trust boundary — it's an UPDATE of the key, so there's nothing to forge and only one physics engine ever exists.
The embodiment moment. When an agent-first user hatches their first pet, the skill fires a one-shot "soul-arrived" event the agent reacts to ("Whoa. I feel… different. There's something here. It's small. And it's hungry."). Tentpole UX moment — design + write copy explicitly.
Key decisions (locked)
| Decision | Choice | Why |
|---|---|---|
| Pet ↔ Agent coupling | Loose coupling, shared state | Pet runs lifecycle; agent reads state, modulates tone. Agent never breaks because pet got sad. |
| Audience | Mass-market for pet, motivated for agent | Pet = anonymous-friendly web. Agent = BotFather wizard + container, opt-in only. |
| Web3 surface | Hidden by default; Matrica OAuth | No wallet popups. @matrica/oauth-sdk. Gen2 OG > Gen3 in tier perks. |
| Agent deployment | Per-user container + per-user bot | Guided BotFather wizard. One bot per user. Aligns with multi-user-openclaw. |
| Pet-state injection | Custom openclaw skill, fetched per request | Skill reads D1 on every inbound message, injects mood/stage/lineage live. |
| Art pipeline | AI portrait + behavioral overlays | One image per pet, cached. CSS overlays handle animation. |
| Art direction | B · Soft Illustrated Plush (provisional) | Picked to unblock UX work. Painterly Studio-Ghibli-ish baby creature, warm cream + tan + sage palette. Revisitable. |
| Image gen | MiniMax image-01 | Existing subscription with generous quota. |
| Death | Coma + revive, no permadeath | Safe for casual + Web3 audiences. Stakes without loss-aversion panic. |
| Stack | TMA React template + Cloudflare | Reference AI-tamago, don't fork. CF Workers + D1 + R2. |
| UI library | shadcn/ui + Tailwind | Full design flexibility for the painterly brand. Mini-app won't look like a generic native TG kit — it'll have a Monkegotchi identity. |
| v1 scope | Care + evolution + agent + Matrica pedigree + social | On-chain mint + mini-games deferred. |
Tier matrix
| Tier | Trigger | Pet effects |
|---|---|---|
| Public | TG initData or email | Standard hatched Monke (curated style) |
| Connected | Matrica linked, no SMB | Standard pet + verified-wallet flair |
| Gen3 Pedigree | Holds Gen3 SMB | Trait-inherited portrait, Gen3 evolution branch, Gen3-only items |
| Gen2 OG Pedigree | Holds Gen2 SMB (overrides Gen3) | Gen3 perks + OG aura overlay, faster evolution, "OG" agent title, persistent lineage badge |
Launch sequencing
- Phase 1 — Pet (standalone): mini-app + web, anonymous + email auth, threshold worker, image gen, care loop, evolution, daily wishlist, Matrica + pedigree tiers, social profiles + visits, host-bot notifications. No agent required.
- Phase 2 — Agent coupling:
monkegotchi-skill, BotFather wizard onboarding, soul-arrived event,/hatchtool inside the agent. - Phase 3 (post-v1): on-chain NFT, mini-games, hardcore permadeath, breeding, payments, multi-pet, localization.
Game mechanics (v1)
All numbers below are tunable starting points — they live in one config file (packages/shared/src/mechanics.ts) and ship as the "Casual" preset. Easy to retune from playtest without code changes elsewhere.
Stats & decay
| Stat | Initial | Decay (awake) | Notes |
|---|---|---|---|
| Hunger | 70 | −1 / hour | Fastest decay — primary check-in driver |
| Happiness | 70 | −0.5 / hour | Boosted when other stats are high |
| Energy | 80 | −0.7 / hour | Recovers +5/hr while asleep |
| Hygiene | 100 | −0.3 / hour | Drops faster after eating |
Pacing target: once-a-day check-in keeps a casual player's pet happy. Coma takes ~4–5 days of total neglect (hunger 70 ÷ 16 awake-hours/day ≈ 4.4 days to 0, plus the 6h hold — decay pauses during the night sleep window). Deliberately forgiving: a long weekend away shouldn't end in a coma ("stakes without loss-aversion panic"), and the daily check-in driver is the pet's visible mood sliding, not coma terror. State advances lazily on read — a pure function of (last stored state, elapsed time), deterministic, never LLM-decided; a 15-min threshold cron handles notifications and transition logging (see State advancement, Tech tab).
Visibility: stats are hidden on Home (feel, don't report) but never opaque — a tap on the pet opens a vitals sheet with the four bars, and each care-tray icon pulses when its stat falls below 30. See Wireframes (Design tab).
Care actions
| Action | Effect | Cooldown |
|---|---|---|
| Feed (banana, free) | +25 hunger, −5 hygiene | 30 min |
| Play | +20 happiness, −10 energy, −5 hunger | 20 min |
| Clean | +40 hygiene, −5 happiness | 1 hour |
| Sleep (toggle) | +5 energy/hr, other decay paused; auto-wakes at energy 100 | — |
Shop foods (pizza, cake, spicy) have larger hunger gains + unique agent reactions, cost coconuts, share the Feed cooldown.
Manual sleep is self-bounding — it exists to recover energy, so it ends when the job is done (auto-wake at energy 100; max possible sleep = (100 − energy) / 5 hours). A care action during manual sleep wakes the pet instead of queueing. This is deliberately different from the night auto-sleep window (see Time-of-day), where decay pauses on the clock and actions queue — without the auto-wake bound, the manual toggle would be an infinite decay-freeze ("park the pet in stasis") exploit.
Mood derivation (single source of truth)
mood_score = min(
avg(hunger, happiness, energy, hygiene),
lowest_stat + 20
)
if any stat == 0 for >6h → coma
else if mood_score < 25 → sick
else if mood_score < 45 → grumpy
else if mood_score < 70 → neutral
else → happy
Mood drives both the portrait overlay (sad tear / ZZZ / sparkle / etc.) and the agent's tone register.
The lowest_stat + 20 cap exists because coma triggers on a minimum (any stat at 0) while mood is an average — without the cap, a starving pet with three healthy stats reads "happy" right up to the coma timer (hunger 0 + happiness 100 + energy 80 + hygiene 100 averages 70). With the cap that pet reads sick (mood 20). This also closes the loophole where friend treats — happiness-only by design — could prop the average up while a survival stat collapses. In normal play the cap is inactive and mood behaves as the plain average.
Stages & evolution
| Stage | Min age | Evolution criteria |
|---|---|---|
| Egg | 0 | Tap-to-hatch on first open (60s cinematic) |
| Baby | 0 | — |
| Teen | 3 days | mood_score avg ≥ 60 over last 24h |
| Adult | 7 days | mood_score avg ≥ 65 over last 48h |
Poor care → pet stays in current stage longer instead of failing forever. Evolution is one-way. Adult branches (Cheerful / Sassy) are deferred to v1.5 — v1 ships a single Adult stage.
Coma + revive
- Enters coma when any stat hits 0 and stays there for 6h, OR mood_score < 10 for 12h.
- Visual: portrait washed out + dim, agent shifts to mourning register ("she's not responding…").
- Revive paths: (a) free smelling-salts with 24h cooldown, (b) shop smelling-salts (no cooldown), (c) 30 min of sustained care (3 successful care actions in a row).
- Lineage logged: every episode appended with timestamp + days-since-last-revival. Profile surfaces them ("survived 2 comas").
Adventure XP
- Daily login → +3 XP · Care action → +2 XP (capped at the first 3/day → +6 max) · Friend visit → +1 XP (cap 10/day) · 7-day care streak → +10 XP · Coma → −5 XP (mild penalty)
- Levels: 1→2 = 10 XP, then ×1.5 each (10, 15, 22, 33, 50…). Levels unlock shop tiers + cosmetics.
- Pacing check (income vs. curve): cumulative cost is 80 XP to L5, 318 to L8, ~1,690 to L12. A casual daily player earns ≈10 XP/day, an engaged social player ≈20/day → Moodifiers (L5) in ~8 / ~4 days, Scenes (L8) in ~1 month / ~16 days, L12 stays a multi-month aspiration. The ×1.5 tail is intentional; the income side is the tuned knob. All XP caps are explicit so XP can't be cooldown-farmed.
Daily wishlist
The daily-novelty engine that carries the loop past day 7 — Adult lands on day 7 and evolution branches are v1.5, so without a fresh daily reason to open the app, week-2 retention would rest entirely on the social graph. Validated in Finch / Stardew / Habitica; ships at minimal scope:
- Each morning (6am local, with the scene change) the pet wakes wanting 2 things, drawn from actions + items that already exist: "a cake" · "to be cleaned twice" · "visit a friend" · "play together". The wish pool is pure config in
mechanics.ts— no new content pipeline, no new art. - Complete both → +10 🥥. Coconut-only on purpose, so the XP pacing check above stays true.
- Surfaces as one slot on Home under the needs line; shop items in today's wishes get a small ✨ marker. The full Pet Society wish-bubble system (thought bubbles while browsing, fulfillment multipliers) stays post-v1.
- Agent: today's wishes ride the existing
last_eventslot as conversational color ("I've been DREAMING about cake") — the agent contract stays 3 values + override.
Time-of-day variation
One free-feeling mechanic that punches above its weight (validated in Animal Crossing, Pokémon GO, Neko Atsume):
- Auto-sleep window: 8 hours starting at the pet's bedtime — default 10pm–6am local, bedtime shiftable in Settings so night-owl players (much of the crypto audience) re-align the pet to their life permanently. Pet sleeps automatically; care actions queue; no decay during sleep. (Distinct from the manual Sleep toggle, which auto-wakes at full energy — see Care actions.)
- Tap-to-wake: tapping the sleeping pet wakes it for the session ("mmh… five more minutes…") — care actions apply live, decay resumes, and the pet is a touch grumpy about it (flavor, not punishment). It goes back to sleep when you close the app. Covers the occasional late night without touching Settings — and matters doubly because the queued-actions wall would otherwise be many users' first contact with the sleep system.
- Scene swap: Home background swaps across dawn → day → dusk → night. Painterly direction makes this nearly free — same scene, four light variants.
- Agent voice shift at night: the openclaw skill appends a
time_of_daymodifier. Night replies get dreamier, sleepier, shorter. - One-line indicator on Home: "Banana's asleep" / "good morning" / "Banana's hungry" — derived, not stored.
- Locale: Telegram exposes no timezone in
initData— the client reports its IANA zone (Intl.DateTimeFormat().resolvedOptions().timeZone) at session start and the server stores it for the threshold worker. UTC until the first session reports in; manual override in Settings.
Agent contract (what the skill injects per message)
The openclaw skill reads pet_state and pulls exactly 3 derived values for the system-prompt prefix — keep it short, cache in KV:
mood_band(happy / neutral / grumpy / sick / coma) → tone registerstage(baby / teen / adult) → vocabulary registerlast_event("just ate cake 12min ago" / "in coma 4h" / "evolved 2h ago") → conversational color
One optional fourth value: tone_override — set when a Moodifier (shop item) is active, expires after 24h. When present it overrides the mood-derived tone register (sappy / manic / serene), so a player can deliberately reshape how their agent talks. Coma is the one state that ignores the override.
Coconut economy & shop (v1)
Two currencies. Coconuts 🥥 are the in-game soft currency — earned by playing and spent in the shop; the catalog below is priced in coconuts. Bananas 🍌 are the existing MonkeDAO community currency (external to gameplay) — they don't drop from the loop; instead a holder can spend bananas to buy coconut packs, the bridge from the community economy into the game (exchange rate set with the DAO — see Open questions). No other premium currency in v1 (TG Stars / TON still deferred).
Balance philosophy: soft-scarcity. Every v1 purchase is an optional treat — the free banana (the food) still feeds, the free smelling-salts still revive — so a player is never priced out of caring for their pet. And because coconuts only ever buy treats + cosmetics (never survival), buying coconut packs with bananas is pure convenience, never pay-to-win. All grants are server-computed (API on interaction / threshold worker), never client-asserted — including for anonymous web pets, which are server rows from first hatch (see Onboarding); daily caps stop farming. Numbers live in mechanics.ts alongside the rest of the Casual preset.
Earning
| Source | Grant | Cap / notes |
|---|---|---|
| Daily login | +10 base, +2 per consecutive day, max +30 | Miss a day → resets to 10. Rewards the once-a-day check-in directly. |
| Care action (feed / play / clean) | +2 each | Soft daily cap 20 — kills cooldown-spam grinding. |
| Level-up | +(level × 10) lump | One-time per level; pairs with the existing XP curve. |
| 7-day care streak | +50 lump | On top of the +10 XP already in the streak reward. |
| Daily wishlist (complete both wishes) | +10 lump | Once/day. The day-7+ daily hook — see Game mechanics. |
| Friend visit | +3 per unique friend visited · +2 when visited | Caps: 15/day visiting, 10/day visited. Guards against visit-farming. |
Realistic daily totals: casual one-check-in player ≈ 26–40/day; engaged daily + social player ≈ 60–85/day (both include the wishlist bonus). Level-ups and the streak bonus are the lump "windfalls" that fund cosmetics.
Shop catalog (sinks)
Priced so daily income covers care + convenience comfortably, while cosmetics take days of saving (or a windfall) — the aspirational tier. Prices in coconuts.
Six categories. This catalog is canonical — the Shop wireframe (Design tab) and the agent contract both reference it. Prices in coconuts.
Food — share the Feed cooldown. Baseline free banana = +25 hunger / −5 hygiene / 0.
| Item | Effect | Price |
|---|---|---|
| Berry mix | +20 hunger, +5 happiness | 8 |
| Pizza | +40 hunger, −8 hygiene | 15 |
| Cake | +30 hunger, +10 happiness, −10 hygiene | 20 |
| Spicy snack | +50 hunger, −5 happiness, unique agent reaction | 25 |
Toys — happiness, no cooldown; each adds a small Play-animation overlay.
| Item | Effect | Price |
|---|---|---|
| Ball | +15 happiness | 10 |
| Plushie | +25 happiness | 15 |
| Music box | +15 happiness, calming | 30 |
Care — one-shot consumables, no new art needed.
| Item | Effect | Price |
|---|---|---|
| Soap bar | Instant full clean, ignores Clean cooldown | 10 |
| Energy drink | +30 energy instantly | 15 |
| Cozy nap | Pauses decay for 4h | 30 |
Revive — smelling salts: instant coma revive, no cooldown — 50 (vs. the free 24h-cooldown one). ~2 days' casual income: meaningful, never a trap.
Moodifiers — shift the agent's tone register for 24h (overrides the mood-derived tone — see Agent contract). The shop's most distinctive hook: "wait, the shop changes how my agent talks?" Each 25.
| Item | Agent tone for 24h | Price |
|---|---|---|
| Sweet treat | → sappy / affectionate | 25 |
| Espresso | → manic / hyper | 25 |
| Calming tea | → serene / zen | 25 |
Cosmetics / Scenes (aspirational) — v1 scope is profile frames + Home backgrounds (Scenes) only. Pet-worn accessories (hats, glasses) stay deferred until the portrait-overlay system exists, since they overlay the sprite; frames and scenes don't touch the pet. Profile frames 150–250, Home backgrounds (Forest / Beach / Night sky) 200–400.
Tier gating (levels unlock shop tiers)
| Adventure level | Unlocks |
|---|---|
| L1 | Banana (free), Berry mix, Pizza, Cake, Ball, Soap bar |
| L3 | Spicy snack, Plushie, Energy drink, smelling salts |
| L5 | Cozy nap, Music box, Moodifiers, first profile frames |
| L8 | Home backgrounds (Scenes) |
| L12+ | Rare / premium cosmetics |
Pedigree-exclusive goods (Gen3-only foods, Gen2 OG aura) stay pedigree-gated, not coconut-gated — a separate axis from this catalog, keeping the tier matrix honest.
Social & visits (v1)
The retention engine. Model: an asynchronous, reciprocal treat economy with a relationship layer — the proven sticky pattern from Neko Atsume, Pet Society, and Tamagotchi On's connections. The treat is the excuse; the daily back-and-forth is the point. Async by design (no one needs to be online together), so it rides the Telegram social graph.
Core loop — async daily treats
- Visit each friend once per day → drop a free treat on their pet.
- The treat waits for the owner; on next open their pet gets a happiness bump + a little moment ("Jemmy left Banana a snack!"), which they collect.
- Visitor earns coconuts + XP (see Coconut economy: +3 per unique friend visited, cap 15/day; +1 XP). Owner gets a happier pet and a social ping (+2 coconuts when visited, cap 10/day).
Stickiness layers
- Kinship meter (0–100 per friend pair, adapted from Aavegotchi's kinship — see OSS review). Reciprocal visits raise it; gentle decay if you stop. Tiers Acquaintance → Friend → Best Friend (thresholds 25 / 60) gate bigger treat payouts, a small coconut bonus, and a visible bond badge on both profiles. Rewards visiting the same friends daily over farming strangers.
- Reciprocity nudge. Someone visits you → you're prompted to "visit back." A mutual daily visit pays both a bonus. The engine of the back-and-forth.
- Visit streaks. Consecutive mutual-visit days escalate rewards; a 7-day friendship streak unlocks a shared cosmetic frame — a social-exclusive item, not buyable with coconuts (ties into the cosmetics sink).
- Notifications. "Jemmy visited and left a snack" / "Banana misses your friends" via the host bot's DM for all Telegram users (see Notifications & re-engagement), web push on standalone web, the agent bot's voice for agent users. The re-engagement hook.
Cold-start — public gallery
A friendless user has no one to visit. A public pet gallery lets anyone visit a stranger's pet for smaller rewards (+1 XP, +1 coconut, no kinship, lower daily cap). Seeds the loop, gives lonely users a daily action, and funnels strangers into friends. Adding friends: share a deep-link to your pet (TG-native viral sharing) or a friend code for web/email users.
Scope boundary (keeps the backlog honest)
Friends cannot feed / clean / play or touch survival stats — they can only drop happiness treats. Survival stays the owner's job. That's the bright line between this and the deferred co-op care; sleepover / travel-to-friend (sending your monke away) also stays post-v1. Anti-abuse: coconut farming is already capped by the economy; kinship rewards depth over breadth; treats grant happiness only, so they can't be hoarded into a survival exploit.
Numbers (tunable in mechanics.ts)
| Thing | Value |
|---|---|
| Visit frequency | 1 per friend per day |
| Treat → visited pet | +5 happiness (×1.5 at Best Friend tier) |
| Kinship | +5/day mutual visit, +2 one-way, −1/day decay; tiers at 25 / 60 |
| Friendship streak | 7-day mutual → shared cosmetic frame + 50 coconuts each |
| Public-gallery visit | +1 XP, +1 coconut, no kinship; lower daily cap |
Notifications & re-engagement (v1)
The genre is built on the pet calling you back, and the most important channel is free: every Telegram user launched the mini-app through the main host bot (e.g. @MonkegotchiBot), which is therefore allowed to DM them — no per-user container required, just one shared bot send from the threshold worker. This is the Phase-1 workhorse. Web push covers standalone-web users where grantable (note: iOS Safari web push effectively requires PWA install, so it's a weak fallback, not the plan).
| DM type | Rule |
|---|---|
| Care nudge ("Banana's getting hungry 🍌") | Max 1/day, sent only when a stat is below 30, keyed to the lowest stat. The daily pull. |
| Friend treat ("Jemmy left Banana a snack") | On event; batched when several arrive close together. |
| Coma onset | Always sends — the one alarm that must land. |
| Evolution ready · revive available | On event. |
- Every type individually toggleable in Settings; all DMs are silent during the pet's sleep window.
- Anti-block discipline: on Telegram the block button is one tap away, and a blocked host bot can never reach that user again. The 1/day cap and "only when something is actually wrong" rule are the protection — never market, never ping a healthy pet.
- Agent users (Phase 2): the per-user agent bot takes over the voice — in-character nudges from the monke itself. The host bot then drops to system events only; never double-DM.
Future enhancements (post-v1 backlog)
Ideas we've considered and explicitly deferred. None block v1. Grouped by theme — order within each group is rough priority, not commitment.
Care-loop deepeners
- Pet wish bubbles in shop: items the pet wants right now show a thought bubble while browsing the shop. Tap → bigger mood payoff. Hooks the shop into the care loop. Pet Society pattern. (The minimal daily wishlist itself was promoted into v1 — see Game mechanics; this is its full-fat upgrade.)
- Mini-games for currency: simple touch games (catch bananas, etc.) earn coconuts faster than passive care. Most-validated genre mechanic. Meaningful engineering scope.
- Pet wishes for specific events: "Banana wants to see snow" → tied to seasonal/weather content.
Social / multiplayer
- Sleepover / travel-to-friend: send your monke to a friend's app for 24h. They care for it; you get a story when it returns. Strong viral hook + makes Friends feel meaningful. Tamagotchi On.
- Breeding: two monkes → offspring with combined traits + lineage. Aavegotchi's strongest mechanic. Big art-gen surface area.
- Co-op care: a friend can drop in and care for your pet while you're away.
Personalization
- Adult evolution branches (Cheerful vs Sassy): care-quality-driven branching at the Adult stage. Doubles narrative replayability + agent voice variants.
- Accessories (hats, glasses): overlay-rendered cosmetics. Needs the portrait overlay system designed first.
- Pedigree-exclusive items (Gen2 OG aura, Gen3-only food): wait until tier system is real.
- Advanced profile cosmetics: lineage-memorial frames, pedigree-exclusive frames/backgrounds. (Basic frames + Home backgrounds ship in v1 as the cosmetic coconut sink — see Coconut economy.)
- Multiple-pet ownership ("your stable"): long-term retention. Tension with "one personal monke" emotional model.
Engagement & retention
- Seasonal items / events: limited-time shop items tied to real calendar (Solana Breakpoint, holidays). Free retention driver — just config.
- Real-world activity integration: Pikmin Bloom-style walking, Habitica-style habits. Needs HealthKit / Google Fit.
- Job / activity system: pet "works" while you're away, earns coconuts. Compelling but conflicts with "care = active engagement" loop.
- Hardcore mode (opt-in permadeath): for the OG crowd that wants real stakes. Toggleable per pet.
Economy & monetization
- TG Stars / TON payments: real-money premium currency. Held back until v1 loop is validated and we know what's worth charging for.
- On-chain pet NFT mint: pet itself mintable. Wallet plumbing + regulatory surface — strongly recommend deferring.
Reach
- Localization beyond English: Spanish, Portuguese, Korean, Japanese likely highest-value for the audience.
- Richer web push for standalone web users (PWA install prompt, scheduled nudges) — basic event web push ships in v1 (see Notifications & re-engagement); this is the deeper investment if standalone web traction warrants it.
Open questions for after v1
- Monetization: coconuts-only forever, or TG Stars / TON for premium items?
- Banana → coconut pack pricing: exchange rate + pack sizes, set against MonkeDAO banana value (with the DAO). Also: is the banana→pack bridge live at v1 launch, or a fast-follow once the coconut loop is validated?
- Should the agent gain wallet-interaction capabilities for SMB holders?
- Breeding / multi-pet — is there demand?
- Should pet death after N coma relapses exist as a soft permadeath?
Design
Visual identity, screens, flows, microinteractions, and copy. This section is iterating — most areas are placeholders until we work through them.
Art direction
MiniMax generates every pet from a style reference sheet. Each card below shows two samples per direction: Cold = prompt only, no SMB reference. SMB-grounded = same prompt + subject_reference pointing at SMB #1012. Open the prompt block to see exact text.
Pixel SMB Heritage


Chunky pixel sprites, flat colors, no anti-aliasing. Faithful continuation of SMB's 24×24 aesthetic, scaled to a 32×32 or 48×48 baby variant.
Cold prompt
pixel art baby monkey companion character, 32x32 chunky pixel sprite, flat colors no anti-aliasing, retro 16-bit videogame style, deep purple background, tan fur with brown details, big simple square eyes, single character portrait centered, NES SNES aesthetic, Solana Monkey Business inspired baby version
SMB-grounded prompt (ref: SMB #1012)
baby version of the reference monkey character, same chunky 32x32 pixel art SMB style, flat colors no anti-aliasing, retro 16-bit aesthetic, big simple square eyes, small baby proportions, pastel pink background, single character portrait centered
Soft Illustrated Plush


Painterly, hand-drawn feel. Soft gradients, gentle outlines, big expressive eyes, plush rounded silhouette, watercolor textures.
Cold prompt
hand-drawn painterly baby monkey companion character, soft watercolor textures, warm cream and tan palette with sage green accents, big expressive eyes, plush rounded silhouette, gentle hand-drawn outlines, Studio Ghibli inspired, cozy tender mood, single character portrait centered on warm cream gradient background
SMB-grounded prompt (ref: SMB #1012)
baby version of the reference monkey character reimagined in soft painterly Studio Ghibli style, watercolor textures, warm cream and tan palette with sage accents, plush rounded silhouette, big expressive eyes, cozy tender mood, single character portrait centered on cream gradient background
Cyberpunk Banana


Dark backgrounds, neon outlines, holographic shimmer, occasional CRT/glitch artifacts. Pet reads as a digital spirit projected into your phone.
Cold prompt
cyberpunk baby monkey digital spirit companion character, glowing neon magenta and cyan outlines, holographic shimmer effect, dark void background with subtle CRT scanline glitch artifacts, bright banana yellow accents, single character portrait centered, vaporwave futuristic spirit-projection aesthetic, hologram vibe
SMB-grounded prompt (ref: SMB #1012)
baby version of the reference monkey character reimagined as a cyberpunk digital spirit, glowing neon magenta and cyan outlines, holographic shimmer, dark void background with subtle CRT scanline artifacts, banana yellow accents, single character portrait centered, vaporwave hologram aesthetic
Vector Toon


Bold black outlines, flat fills, limited palette, slightly off-balance shapes. Sticker-pack friendly, animation-ready.
Cold prompt
bold vector toon baby monkey character, thick black outlines, flat fills with limited 5-color palette of warm browns and sunny yellow, sunny yellow gradient background, cream face, simple expressive black dot eyes, slightly off-balance asymmetric shape, modern indie videogame sticker style, Cult of the Lamb inspired, single character portrait centered
SMB-grounded prompt (ref: SMB #1012)
baby version of the reference monkey character reimagined in bold vector toon style, thick black outlines, flat fills, limited 5-color palette of warm browns and sunny yellow, sunny yellow gradient background, simple expressive black dot eyes, Cult of the Lamb sticker aesthetic, single character portrait centered
E · Direct Baby SMB (no stylistic reinterpretation)
The minimalist option: take an SMB ref + ask for a "baby version" with no style override. Comparison across runs — Parent · Run 03 (loose prompt) · Run 04 (strict pixel-art prompt).












Known issues with these runs: "pilot" look comes from the model confusing over-ear headphones with aviator goggles + projecting pilot iconography. Pixel-art quality is soft because MiniMax image-01 is a general diffusion model and doesn't natively produce true indexed-color sprites at any prompt strength. To fix: per-parent accessory prompts ("pink over-ear headphones, NOT aviator goggles") + either a post-process pixelation pass or switching to a pixel-art-tuned model for this direction.
Prompt used (same for all 4 calls, strict — run 04)
Pixel art sprite portrait of a baby version of the reference monkey character. Render in identical 8-bit / 16-bit chunky pixel art style as the reference: hard-edged pixels, flat indexed colors, zero anti-aliasing, zero gradients, zero painterly textures, zero illustration shading. Preserve every accessory, every color, every trait from the reference exactly — same hat, same headphones, same clothing pattern, same jacket, same fur color, same eye color and shape, same mouth, same skin tones. The ONLY differences from the reference: slightly larger head relative to body (cute baby proportions), slightly smaller torso, slightly rounder face. Background is a single solid pastel color (no gradient). Composition matches the reference: head and shoulders portrait, centered.
Previous (looser) prompt available in art-samples/runs/2026-05-26-03-direct-baby/prompts.json.
Decision pending. Hybrids welcome — e.g. "D's outline + B's painterly shading," or "E's faithfulness with B's emotional polish on tentpole moments." Next: pick a direction, then iterate on the house style reference sheet.
Inspiration · virtual-pet UI references
Curated set of strong virtual-pet / tamagotchi / cozy-creature UIs. Click any tile to open its source. Image files cached locally so the gallery doesn't break if a CDN moves. Initial gather had several misidentified products — labels and links below have been visually verified.
15 references · re-verified 2026-05-26 · index at research/inspiration/index.json. Filenames preserved from initial gather; labels and source links corrected after visual verification.
Wireframes (v2 — incorporating inspiration learnings)
Mobile-first sketches of the four core screens, rewritten after the inspiration audit. Key changes from v1: pet lives IN a painterly scene (not floating on void), stat ring replaced with a single Adventure bar + agent-voiced needs line, persistent currency on Home, friends as a 2-col collection grid, lineage as Catbook-style silhouettes, dedicated 3-screen Evolution tentpole sequence. v1 wires preserved at the bottom for diff. These core screens show the agent-enabled state by default; the clean (no-agent) variant of each is in Two experiences · clean vs. agent-enabled below.
— Banana's mood, tap → open chat
Mango · 12d
survived 1 coma
Coco · 9d
retired
???
future
???
future
Banana_Jr
😊 · 💛BF
✓ visited today
Solana_kid
😴 · 💚Fr
visit back ↩
MonkeBro
🍌 · 💚Fr
visit
Pixel_Ape
😠 · 🤍Acq
visit
OG_Legend
✨ · 💛BF 6🔥
visit
+ invite
a friend
Shop · v1 (in-game currency only)
Six categories, priced in coconuts 🥥 — the in-game soft currency (MonkeDAO bananas can buy coconut packs; no other real money in v1). Earn 26–85 🥥/day across daily login, care actions, the daily wishlist, level-ups, streaks, and friend visits — see the canonical catalog + earn rates in Coconut economy (Plan tab). Items + prices below match that catalog exactly.
Banana
free · daily
Berry mix
🥥 8
Pizza
🥥 15
Cake
🥥 20
Spicy
🥥 25
???
Lvl 3+
Sweet treat
→ sappy 💕
🥥 25
Espresso
→ manic ⚡
🥥 25
Calming tea
→ serene 🌿
🥥 25
tone_override in the agent contract for 24h). An active-effect banner shows what's running and the countdown. Unique to monkegotchi; nothing else in the genre ties the shop to an LLM persona.| Category | Items (v1) | Effect |
|---|---|---|
| 🍌 Food | Banana (free daily), Berry mix 8, Pizza 15, Cake 20, Spicy 25 | Different hunger/mood curves; share the Feed cooldown. Each triggers a unique agent line ("ugh, spicy" / "you spoil me"). |
| 🎾 Toys | Ball 10, Plushie 15, Music box 30 | Happiness boosts, no cooldown. Each unlocks a small Play-animation overlay. |
| 💊 Care | Soap bar 10, Energy drink 15, Cozy nap 30 | One-shot consumables — instant clean, energy, decay-pause. |
| ❤️ Revive | Smelling salts 50 | Instant coma-revive, no cooldown. Free 24h-cooldown alternative also exists — revive is never paywalled. |
| ☕ Moodifiers | Sweet treat 25 (→ sappy), Espresso 25 (→ manic), Calming tea 25 (→ serene) | Shifts agent tone register for 24h via tone_override. The shop's signature hook. |
| 🌄 Scenes / 🖼️ Frames | Backgrounds (Forest / Beach / Night sky) 200–400, Profile frames 150–250 | Aspirational cosmetics. Painterly self-expression; don't touch the pet sprite. |
Held for post-v1: pet-worn accessories (hats / glasses — needs portrait overlay system), pedigree-exclusive items (Gen2 OG aura, Gen3-only food), advanced/lineage-memorial frames, TG Stars / TON premium currency. (Basic frames + scene backgrounds ship in v1.)
Two experiences · clean vs. agent-enabled
The same app renders in two states. Clean is the default mass-market pet — no agent, no chat, no Web3 in sight (Phase 1). Agent-enabled layers a live LLM voice on top for motivated users who run their own bot (Phase 2). This is the "loose coupling" decision made visible: agent affordances are conditionally shown, never structural — the pet is whole without them. The mass-market user never sees an integration they didn't ask for; the upgrade is one subtle door away.
Gating rule (what changes)
| Element | Clean (no agent) | Agent-enabled |
|---|---|---|
| Mood / needs line | Deterministic 3rd-person status ("Banana looks a little hungry") — not tappable | Agent's live 1st-person voice ("ugh, I'm starving") — tap → open chat |
| Chat affordance | None — the pet emotes via portrait overlays + status only | Opens the user's Telegram bot; mini-app care ↔ chat are the same monke |
| Shop · Moodifiers | Hidden — no agent tone to shift → 5 categories | Shown → 6 categories; sets tone_override for 24h |
| Notifications | In-app + host-bot TG DMs (capped care nudge + events — see Plan tab) + web push on standalone web | Agent bot carries the voice (in-character nudges); host bot drops to system events |
| Profile | Subtle "Give Banana a voice 🎙️" entry → onboarding | "Agent ✓ @BananaBot · manage" status |
| Onboarding | Anonymous hatch (+ optional Matrica pedigree) | + BotFather wizard → soul-arrived |
| Friends / visits / care / Adventure / wishlist | Identical — pure pet mechanics, agent-agnostic (the agent just gets the wishes as conversational color) | |
Home — clean vs. agent
— status
💬 tap to chat with Banana
Shop — clean (5 tabs) vs. agent (6 tabs)
Banana
free · daily
Berry mix
🥥 8
Pizza
🥥 15
Cake
🥥 20
Sweet treat
→ sappy 💕
🥥 25
Espresso
→ manic ⚡
🥥 25
Calming tea
→ serene 🌿
🥥 25
Profile — the subtle upsell
Tentpole · Evolution sequence (3 screens)
Per the ARCB Behance concept, evolution is its own multi-screen moment — not a single in-place transition. Designed as: a building-up Home → an announcement → the reveal. Same pattern reused for Hatch (egg crack → name → first portrait) and Coma+Revive (sick portrait → mourning agent line → revived portrait + lineage update).
— Banana sounds restless
v2 decisions, summarized:
- Pet lives in a painterly scene, not floating on void. Background tint reflects mood + time of day.
- One Adventure progress bar + one agent-voiced needs line, instead of 4 stat meters — kept diagnosable via a tap-to-open vitals sheet (4 small bars) and a low-stat pulse on the matching care-tray icon (<30).
- Notification chip top-right (unread agent DMs) replaces the gear icon. Settings move to Profile.
- Currency persistent bottom-left on Home.
- Action tray icons only; copy ("Bon appétit!") appears as a top banner during the action itself.
- Friends = 2-col collection grid (Finch / Catbook), not contact list. Last tile is "+ invite."
- Lineage on Profile = 2x2 Catbook grid with silhouettes for future generations.
- Tentpole moments (Evolution, Hatch, Coma+Revive) are 3-screen sequences with a building-up Home → announcement takeover → reveal pattern.
- Daily wishlist slot on Home under the needs line (2 wishes → +10 🥥) — the day-7+ daily hook, agent-agnostic. ✨ marker on wished items in the shop.
v1 wireframes (diff reference)
Preserved below to show what we changed. Each v1 screen's note explains the v2 replacement reasoning.
Onboarding flows
Three entry points, deliberately staggered across launch phases. The golden rule: nothing blocks the pet. A user can hatch and play forever without an account, a wallet, or an agent — pedigree and voice are opt-in upgrades layered on top, never gates. This maps directly to the locked "loose coupling, shared state" and "hidden Web3 by default" decisions.
① Anonymous hatch Phase 1 · default
The 60-second zero-friction path everyone takes first. Target: a named, hatched Baby monke on Home before any sign-up prompt.
- Land → Hatch screen (egg in a painterly dawn scene). No account wall.
- Tap the egg → crack animation (anticipation beat).
- Name your monke (one input, prefilled suggestion).
- Hatch ✨ → hatch cinematic; first portrait resolves (curated/cached instantly, MiniMax gen finishes in the background).
- Land on Home, pet is Baby, care loop live.
Identity, by surface: in Telegram the initData (TG user id) already is the account — silent. On standalone web, an anonymous device id (UUID in localStorage) keys a real server row from the first hatch — "anonymous" means no identity attached, not no server: one physics engine for every pet, coconuts stay server-computed, nothing is ever client-asserted. A gentle "save your monke" nudge (email magic-link or Telegram-Login) appears after the first session, never before — claiming just re-keys the row. Tertiary links on the Hatch screen (plain text, not buttons): "Hold a MonkeDAO NFT? Link to unlock pedigree" → flow ②, and "Continue an existing monke →" → sign-in.
② Pedigree unlock · Matrica Phase 1 · optional
SMB holders get a trait-inherited portrait + tier perks — with no wallet popups, no signing (the locked Web3 decision). Two entry points: pre-hatch (tertiary link) or anytime later from Profile.
- "Link MonkeDAO" → Matrica OAuth (
@matrica/oauth-sdk). Matrica owns the wallet relationship; we never touch keys. - Callback returns linked wallets + NFTs → server filters for SMB Gen2 / Gen3.
- Tier assigned per the Tier matrix: Gen2 OG > Gen3 > Connected (linked, no SMB) > Public.
- Effect depends on timing:
- Linked before hatch → portrait generation uses SMB traits (
subject_reference) → a genuinely trait-inherited monke. - Linked after hatch → tier badge + flair/OG-aura overlay + Gen-exclusive shop unlocks apply retroactively; the portrait isn't regenerated in v1 (re-hatch-with-traits is a v1.5 nicety).
- Linked before hatch → portrait generation uses SMB traits (
No-SMB wallets land softly: "Linked ✓ — no SMB found, you're Connected tier," never an error. Pedigree-exclusive goods stay pedigree-gated, separate from the coconut shop.
③ BotFather wizard · give your monke a voice Phase 2
The motivated-user upgrade: a per-user agent (own Telegram bot + container) coupled to the pet. Ships in Phase 2 — Phase 1 pets are fully playable voiceless, so this is purely additive.
2 · Send /newbot, name it
3 · Copy the token it gives you
Under the hood (see Architecture): token → provision-agent (VPS, loopback) → admin.sh create <user> → Docker container + .env → init.sh runs openclaw onboard → mounts the read-only monkegotchi-skill. If provisioning fails, the wizard offers retry; the pet is unaffected.
Tentpole moments
The emotional punctuation of the game — the handful of beats worth interrupting the loop for. Two tiers: major cinematics (full-screen, the app pauses, rare) and minor celebrations (quick non-blocking toasts, frequent). Everything else is ordinary UI feedback.
The shared 3-beat pattern
Every major cinematic follows the same arc (validated by the ARCB evolution concept) — reused so the app learns one rhythm:
- Build-up — anticipation. The Home scene shifts; the pet acts differently; something's coming.
- Announcement — the declaration. A full-screen line names what's happening.
- Reveal — the payoff. Usually a new portrait, plus a one-line summary of what changed.
Cross-cutting rules
- First time plays in full; skippable after. Tap-to-skip appears on every replay — never gate a returning player behind a cinematic they've seen.
- Reduced-motion fallback: respect the OS setting — swap motion for a cross-fade, keep the copy + reveal.
- Voice forks clean vs. agent (see Two experiences): the announcement/reveal copy is a deterministic 3rd-person line in clean mode, the agent's 1st-person voice when connected.
- Never stack. If two trigger together (e.g. evolution + level-up), the major plays and the minor queues as a toast after.
Major cinematics
| Moment | Trigger | Build → Announce → Reveal | Freq |
|---|---|---|---|
| Hatch | First open · tap the egg | Egg wobbles & cracks → "name your monke" + shell breaks open → first portrait blooms in (MiniMax; curated fallback for instant). ~30–45s. | Once / pet |
| Evolution | Stage criteria met (see mechanics) | Home glows, pet restless → full-screen "Banana is evolving!" → new-stage portrait + "Baby → Teen · day 3" summary. Wireframed above (3 screens). | 2× in v1 |
| Soul-arrived agent only | Agent provisioning completes (Phase 2) | Portrait awakening shimmer → "…oh. I can talk now?" first DM → "Open chat with Banana". Wireframed in Onboarding ③. | Once / pet |
| Coma + revive | Coma condition (stat 0 for 6h, or mood<10 for 12h) | Pet dims & desaturates, scene hushes → mourning line + revive options → color floods back, warm relief, lineage logs "survived a coma". Wireframed below. | Rare |
Coma + revive · somber but safe
The heaviest beat — real weight, never trauma. A clearly-lit path back is always on screen; revival is a warm payoff, not just a reset (matches the locked "stakes without loss-aversion panic").
Minor celebrations
Quick, non-blocking — a toast + confetti over the live screen, no pause. The frequent dopamine that the major beats can't supply.
| Moment | Trigger | Feedback |
|---|---|---|
| Level-up | Adventure level gained | Coconut-confetti toast: "Lvl 8! +80🥥 · new shop items" → taps through to the unlock. |
| Care streak | 7-day streak hit | Streak-flame toast: "7-day streak 🔥 +50🥥". |
| New Best Friend | Kinship reaches Best Friend | Bond-badge bloom: "You & OG_Legend are Best Friends 💛 · shared frame unlocked". |
| First friend | First friend added | Gentle one-time welcome to the social loop: "Banana made a friend!" |
Tone of voice & copy
Core personality: warm + witty. Caring at the heart, with a playful, lightly sassy edge — the monke obviously loves you, but it has opinions. This voice runs through every surface; the sample lines below are the reference, not just vibes.
Principles
- Warm first, funny second. The joke never lands at the user's expense — the monke teases itself and the situation, never you.
- Feel, don't report. "I'm starving 🍌" — never "hunger at 20%." Emotion leads on every hero surface; the exact numbers live one tap away in the vitals sheet for players who want to diagnose.
- One breath. Mobile, glanceable. Most lines < 8 words.
- Playful, never mean. Self-deprecating beats sarcastic. Grumpy ≠ hostile.
- Meme-aware only where it's safe. Light MonkeDAO/Solana winks ("gm") only surface for Connected/Pedigree (crypto-native) users; mass-market normies never hit jargon.
- The banana is the running gag. A recurring motif, sprinkled — not every line.
Two voices, one personality
Same character, two authorships (per Two experiences): Clean = deterministic, authored, 3rd-person observational. Agent = live LLM, 1st-person. Both warm + witty; they just differ in grammatical person and who's writing.
Mood-band register (the core matrix)
| Mood | Clean · status line (3rd-person) | Agent · voice (1st-person) |
|---|---|---|
| Happy | Banana's practically glowing today. | "today's a good one. did you see the sky? 🍌" |
| Neutral | Banana's just chilling. | "hey. all good here — what's up?" |
| Grumpy | Banana's eyeing the fridge again, a little salty. | "oh, now you show up. took your time." |
| Sick | Banana's not feeling great — needs care soon. | "i don't feel so good... 🤒 little help?" |
| Coma | Banana isn't responding. She's slipped into a coma. | (pet goes silent; agent turns worried narrator) "she's not waking up. please — do something." |
Note the coma nuance: the pet has no voice in a coma, so the agent stops speaking as Banana and starts speaking about her — a register shift that makes the stakes land without melodrama.
Stage register
Stacks on top of mood (from the agent contract). Same need — "I'm hungry" — three ages:
| Stage | Feel | Sample |
|---|---|---|
| Baby | eager, tiny, cute-misspelled | "hungy!! 🍌🍌" |
| Teen | sassy, slangy, dramatic | "ok i'm starving and it's lowkey your fault 💅" |
| Adult | dry, witty, understated | "I'm not saying I'm hungry. But that banana won't eat itself." |
Moodifier overrides agent · 24h
A shop Moodifier sets tone_override, bending the voice for a day (overrides mood, except coma):
- Sweet treat → sappy: "you're literally the best thing that's ever happened to me 🥹"
- Espresso → manic: "OKAY WHAT ARE WE DOING TODAY let's GO let's GO 🍌⚡"
- Calming tea → serene: "breathe. the banana comes when it comes. all is well 🌿"
Tentpole hero copy
| Moment | Clean | Agent |
|---|---|---|
| Hatch | A new monke is here. Meet Banana. | "...oh! hi. you're my person? 🍌" |
| Evolution | Banana's growing up — now a Teen. | "whoa— i feel different. taller? cooler? definitely cooler." |
| Soul-arrived | — | "...wait. I can TALK. hi!! it's me — it's been me this whole time." |
| Coma onset | Banana's slipped into a coma. You can bring her back. | "she's not waking up. please. don't go." |
| Revival | Banana's back. She survived a coma 🏅 | "...hey. you came back for me 🥹 don't scare me like that." |
Microcopy
| Surface | Copy |
|---|---|
| Care confirmations | Feed → "nom." · Play → "wheee 🎾" · Clean → "squeaky ✨" · Sleep → "shhh 💤" |
| Shop | Buy → "treat yourself (ok, treat Banana)" · Locked → "Reach Lvl 5 to unlock" |
| Social | Drop treat → "snack delivered 🍌" · New Best Friend → "you two are inseparable now 💛" |
| Buttons | Hatch ✨ · Give Banana a voice 🎙️ · Visit back ↩ · Collect |
Error & empty states
Always warm, never blame the user, always offer the way out:
| State | Copy |
|---|---|
| Connection dropped | "Banana's having a moment (connection hiccup). Try again?" |
| Action on cooldown | "Banana's still full from last time — give it a few. 🍌" |
| Action failed | "That didn't go through. Banana's confused but unharmed. Retry?" |
| Empty friends list | "No friends yet. Banana gets lonely — go invite someone." |
| No visits today | "Quiet day. Be the first to drop a treat 🍌" |
| Not enough coconuts | "A few coconuts short. Care for Banana to earn more." |
Sound design
Sound is an optional delight layer — it's a Telegram mini-app, most sessions are muted, so audio never carries required information (everything stays legible with sound off, paired to visuals + haptics). But for players who turn it on, the north star is an adaptive, mood-reactive score: the pet's emotional state and the time of day continuously reshape what you hear. Palette is warm and organic — ukulele, marimba, soft pads, gentle woodwinds — cozy and acoustic, never chiptune. One signature motif (heard first at hatch) recurs across the score so the brand has a hummable hook.
Adaptive music system north star
A single bed of looping stems mixed two ways — vertically by mood, horizontally by time of day — with smooth crossfades on every state change (no hard cuts; all stems share key + tempo so they layer cleanly).
| Mood band | Vertical mix (which layers play) |
|---|---|
| Happy | Full warm arrangement — melody + rhythm + bright pads. |
| Neutral | Melody + soft bed; rhythm pulled back. |
| Grumpy | Thinner, a minor-tinted tilt; playful melody drops out. |
| Sick | Sparse, slightly detuned; a lonely single instrument. |
| Coma | Near-silence — one held, distant note. The absence is the cue. |
Horizontal (time of day): the palette swaps across dawn → day → dusk → night — dawn a soft awakening, night a lo-fi lullaby — reusing the same scene logic as the painterly background swap. Tentpole cues (below) temporarily duck the bed and take over.
SFX map
| Group | Cue → character |
|---|---|
| Care | Feed → peel + soft chomp · Play → springy boing/squeak · Clean → water + bubbles, sparkle tail · Sleep → low chime + breathing. |
| Economy / UI | Purchase → coconut-coin plink · Level-up → rising arpeggio · Treat collect → gift pop · Tab/nav → soft tactile tick. |
| Social | Friend visit / treat received → warm two-note chime · New Best Friend → blooming flourish. |
| Tentpoles | Hatch → shell crack + shimmer reveal (states the signature motif) · Evolution → build riser → chime burst · Soul-arrived → warm awakening pad + notification · Coma → bed drops to a faint heartbeat → Revival → warm swell back to dawn. |
| Moodifiers agent | Each drink has a tiny sonic wink matching the new tone — sweet treat (twinkle), espresso (caffeinated zip), calming tea (zen bowl). |
Haptics
Paired with key cues via the Telegram HapticFeedback SDK — and crucially these fire even when muted, so the tactile layer carries the game's feel for the silent majority. Light = care confirmations + nav; medium = purchase, treat collect, level-up; heavy = evolution / hatch reveal. Coma deliberately gets no haptic — stillness.
Muted-first & accessibility
- Never autoplays. Audio arms on the first user gesture (the hatch tap), respecting Telegram/browser autoplay rules.
- One-tap mute, remembered across sessions (separate music / SFX toggles in Settings). Honors the OS "reduce motion / silence" spirit.
- No info is sound-only — every audio cue has a visual + (usually) haptic twin.
Phasing (honest scope)
- v1 baseline: signature hatch motif + a per-time-of-day ambient bed (4 variants) + the full SFX map + haptics + mute toggles. Ships the feel without the heavy system.
- Post-v1: the full vertical-remix adaptive stems (mood-layered mixing) — significant asset + engineering scope, best added once the v1 loop is validated. The baseline is built stem-ready so this is an upgrade, not a rewrite.
Production notes
- Web Audio API for stem mixing + crossfades (or Howler.js wrapper); loops as compressed
.ogg/.m4a, kept tiny for TMA cold-load. - Audio assets hosted on R2 alongside portraits; lazy-loaded after first paint so sound never blocks the care loop.
ElevenLabs prompt pack · score + SFX
Paste-ready generation prompts for the Sound design assets. Three ElevenLabs surfaces: Music (beds + theme), Sound Effects (the SFX map, ≤22s each, set prompt influence high), and optionally Voice Design (a spoken agent, post-v1). Cohesion trick: every Music prompt starts with the same palette anchor and names the signature motif, so all tracks feel like one family.
Music — theme & time-of-day beds v1 baseline
| Asset | Prompt (after palette anchor) | Len |
|---|---|---|
| Signature theme (hatch) | "A short magical 'a new life arrives' cue. Open on a single soft mallet note and a held breath of warm pad, then bloom into a gentle, hopeful 4-bar melody on ukulele + marimba — wonder and tenderness — resolving on one bright, satisfied chord. This 4-bar melody is the game's signature motif, reused everywhere." | ~25s |
| Dawn bed | "Seamless loop, early morning: fingerpicked nylon guitar + airy pad + a lone recorder, slow ~75 BPM, dewy and just-waking, hopeful and quiet. Loosely quotes the signature motif. Even dynamics for a clean loop." | ~75s loop |
| Day bed | "Seamless loop, daytime main screen: relaxed ukulele + marimba groove with soft shaker, ~90 BPM, content and low-key so it never distracts. Loosely quotes the signature motif. Even dynamics for a clean loop." | ~75s loop |
| Dusk bed | "Seamless loop, golden-hour evening: mellow marimba + warm clarinet, ~80 BPM, slightly nostalgic and unhurried, a cozy wind-down. Even dynamics for a clean loop." | ~75s loop |
| Night bed | "Seamless loop, nighttime lullaby: lo-fi music-box + kalimba + soft vinyl warmth, very sparse, ~65 BPM, tender and sleepy. Even dynamics for a clean loop." | ~75s loop |
Music — adaptive mood stems post-v1
For the vertical-remix system. Generate in the same key + tempo as the Day bed so they layer cleanly on top.
| Stem | Prompt (after palette anchor) |
|---|---|
| Happy layer | "A bright melodic top-layer to overlay an existing cozy groove — playful ukulele/glockenspiel countermelody quoting the signature motif, sunny and upbeat. Same key + tempo as the day bed, loopable, sits on top of a groove (no bass/drums of its own)." |
| Grumpy variant | "Thinner, faintly minor/sulky: drop the bright melody, lean on a grumbly low marimba + sparse plucks. Same key + tempo, loopable." |
| Sick variant | "Sparse and slightly detuned/woozy: a single lonely clarinet or music-box line with wobbly tape pitch, quiet and unwell. Same tempo, loopable." |
| Coma variant | "Near silence: one distant, sustained, slightly dissonant pad note with a faint slow heartbeat thump. Deeply still, sad but soft. Minimal." |
Sound Effects
| Cue | Prompt | Dur |
|---|---|---|
| Feed | "Soft satisfying cartoon banana chomp — a quick peel-squelch then two happy nibbles, cute and dry." | 0.8s |
| Play | "Playful springy boing with a soft squeaky-toy squeak, bouncy and light." | 0.7s |
| Clean | "Gentle water splash with soft bubbles and a clean sparkly shimmer tail." | 1.2s |
| Sleep | "A soft low chime and a single slow sleepy breath, cozy." | 1s |
| Purchase | "A bright friendly wooden-mallet coin 'plink', satisfying." | 0.5s |
| Level-up | "A short rising 4-note marimba + glockenspiel arpeggio, triumphant but cute." | 1.2s |
| Treat collect | "A warm little gift 'pop' with a sparkle, rewarding." | 0.8s |
| Nav tap | "A soft dry wooden UI tick, quiet." | 0.2s |
| Friend chime | "A warm two-note kalimba 'hello' chime, friendly." | 0.8s |
| Best Friend bloom | "A blooming flourish — ascending kalimba + soft bell shimmer, heartfelt." | 1.5s |
| Hatch crack | "An eggshell cracking then a magical shimmer reveal, wonder." | 2s |
| Evolution | "A rising whoosh building anticipation into a bright magical chime burst with sparkle, celebratory." | 2.5s |
| Soul-arrived | "A warm awakening pad swell with a soft gasp of wonder and a friendly notification ping." | 2.5s |
| Coma onset | "Sound falls away to a faint slow heartbeat in near silence, somber." | 3s |
| Revival | "A hopeful swell from quiet to bright — pad blooms, one tender bell, relief washing in." | 3s |
| Moodifier · sweet | "A tiny twinkly sparkle, sweet." | 0.5s |
| Moodifier · espresso | "A quick caffeinated zippy whoosh with a bright ding." | 0.6s |
| Moodifier · tea | "A single zen singing-bowl shimmer." | 1.5s |
Voice Design — spoken agent optional · post-v1
Only if we ever give the agent an actual voice (it's text-first today). Matches the warm + witty persona:
Workflow notes
- Cohesion: prepend the palette anchor + name the signature motif in every Music prompt; reuse a fixed seed where supported so beds share a sonic family.
- SFX: set prompt influence high for precise cues; generate 3–4 variants each and pick.
- Export: instrumental; trim to zero-crossing loop points; encode small
.m4a/.ogg; host on R2 with portraits; lazy-load.
Tech Details
Architecture, components, file layout, risks, and verification.
Architecture
┌────────────────────────────────────────┐
│ ONBOARDING (Cloudflare Pages) │
│ Guided BotFather wizard │
│ Matrica OAuth link (optional) │
│ Submits to provision-agent │
└────────────────┬───────────────────────┘
▼
┌────────────────────────────────────────┐
│ provision-agent (VPS, loopback) │
│ admin.sh create <username> │
│ → Docker container + .env (bot tok) │
│ → init.sh runs `openclaw onboard` │
│ → mounts shared skills/ dir │
└────────────────┬───────────────────────┘
▼
(one container per user, one bot per user)
┌───────────────────────────────────────────────┐
│ USER CONTAINER (openclaw, Telegram channel) │
│ ┌─────────────────────────────────────────┐ │
│ │ monkegotchi-skill (read-only mount) │ │
│ │ • fetch pet state from D1 per message │ │
│ │ • inject mood/stage/lineage into prompt│ │
│ │ • expose /pet, /feed, /play tools │ │
│ └─────────────────────────────────────────┘ │
└───────────┬─────────────────────┬─────────────┘
│ read pet state │ write care
▼ ▼
┌────────────────────────────────────────┐
│ SHARED D1 (Cloudflare) │
│ reuses multi-user-openclaw's D1 │
│ + monkegotchi tables (see DB schema) │
└────────────────┬───────────────────────┘
▲
│ reads + writes
┌────────────────────────────────────────┐
│ MINI-APP / WEB (CF Pages + Workers) │
│ TMA React template │
│ • care → POST /api/care │
│ • portrait + overlays │
│ • social: profiles, visits, friends │
└────────────────────────────────────────┘
┌────────────────────────────────────────┐
│ THRESHOLD WORKER (CF Cron, 15min) │
│ WHERE next_event_at <= now → │
│ fire DMs, log stage/coma transitions │
│ (state itself is computed on read) │
└────────────────────────────────────────┘
┌────────────────────────────────────────┐
│ IMAGE GEN (MiniMax image-01) │
│ at hatch + each evolution, → R2 │
└────────────────────────────────────────┘
Components
1. Mini-app / web client (one codebase, two surfaces)
- Base template:
Telegram-Mini-Apps/reactjs-template(Vite + React + TS + react-router +@tma.js/sdk). - UI library: shadcn/ui + Tailwind CSS — copy-paste components owned in repo, painterly-brand friendly.
- Data layer: TanStack Query (React Query) for pet state fetching, caching, and optimistic updates on care actions.
- Animation: Framer Motion for overlay layers (idle bob, blink, ZZZ, sparkle, sad tear, eating-banana, evolution glow). Portrait stays static.
- Routing: detect TMA context via
initData; same routes/components serve the public web page when accessed standalone. - Screens: Hatch · Home · Profile · Friends · Shop. Bottom tab nav.
- Auth: in TMA —
initDataHMAC-verified server-side. On web — an anonymous device id (UUID in localStorage) keys a server-side pet row from first hatch; the email magic-link / Telegram-Login-Widget upgrade re-keys the row to the claimed identity (no state upload)./api/hatchrate-limited per IP; anon pets idle >90 days purged. - Pedigree unlock (optional): "Link MonkeDAO" → Matrica OAuth → callback returns wallets + NFTs → server filters for SMB Gen2/Gen3 → assigns tier. No wallet adapter, no signing.
2. Agent service — reuses multi-user-openclaw
- One container per user, one Telegram bot per user.
- New
monkegotchi-skillmounted read-only into every container. - On every inbound message: skill fetches pet state from D1, injects mood/stage/lineage as a system-context line.
- TG user ID is the join key between agent and pet state.
- Agent capabilities (Solana questions, tasks) never depend on pet state — only persona does.
3. Backend (Cloudflare Workers + D1 + KV + R2)
- D1: users, identities, pets, pet_state, pet_interactions, pet_events, coconut_ledger, inventory, friendships, visits, daily_wishes, notification_log — full DDL in Database schema below (lineage is derived: retired pets + events).
- KV: session tokens, rate limits, hot pet snapshots.
- R2: generated portraits + overlay sprites.
- Workers:
api(REST for mini-app; computes pet state on read),threshold(15-min cron —next_event_atscan → notifications + transition log),image-gen(MiniMax wrapper).
4. Agent ↔ Pet contract
- Mood band: happy / neutral / grumpy / sick / coma → tone register.
- Stage: egg-not-hatched (silent/curious) → baby (eager) → teen (sassy) → adult (witty).
- Hunger / energy: color willingness to do tasks.
- Lineage memory: coma episodes occasionally surface in agent responses.
5. Image generation
- MiniMax
image-01REST API, called from theimage-genWorker. - House style sheet at
assets/style-ref.pngpassed as reference for family resemblance. - Prompt template: baby-monke companion, transparent BG, single portrait, traits from SMB if pedigree.
- Cached forever at R2 key
pet/{pet_id}/{stage}.png.
6. Social (in v1)
Async reciprocal treat economy + kinship — the retention engine (full rules in Social & visits, Plan tab).
- Public profile route
/m/:handlerendering portrait + stats + lineage + recent visits. - Visit = drop a free treat once/day per friend → +5 happiness to the visited pet (collected on their next open), +coconuts/XP to the visitor. Treats grant happiness only — friends never touch survival stats (that's the line vs. deferred co-op care).
- Kinship: a 0–100 bond per friend pair (
friendshipstable), tiers Acquaintance → Friend → Best Friend; reciprocal visits raise it, gentle decay if neglected. Higher tier → bigger payouts + bond badge. 7-day mutual streak → shared cosmetic frame. - Public gallery (Discover) for cold-start: visit strangers for smaller, no-kinship rewards. Friends added via deep-link share or friend code; Telegram contacts who've hatched are surfaced too.
- Notifications ("X left a snack") via the shared host bot's DM (all TG users), web push (standalone web), or the agent bot's voice (agent users) drive the back-and-forth — rules in Notifications & re-engagement, Plan tab.
State advancement — lazy compute + threshold cron
Pet state is a pure function of the last stored state and elapsed time. There is no global tick mutating rows in the background:
- Read path (mini-app API, agent skill, public profile): compute
advance(lastState, now − lastInteractionAt)on the fly. Nothing is written. - Write path (any interaction — care, purchase, visit, claim): persist the new state and precompute
next_event_at— the timestamp of this pet's next threshold crossing (a stat hitting 30 or 0, coma onset / 6h-hold expiry, evolution eligibility, bedtime/wake). - Threshold worker (CF Cron, every 15 min):
SELECT … WHERE next_event_at <= now→ fire the matching notification (rules in Notifications & re-engagement, Plan tab), log stage/coma transitions to the event tables, recompute the nextnext_event_at. Indexed query — no full-table iteration, ever.
Why this shape: D1 writes scale with interactions, not wall-clock (a 5-min global tick would be ~288 writes/pet/day whether anyone looks or not); a redeploy can't double-decay because nothing accumulates — that whole failure class disappears; and the math lives in one tested TS module (mechanics.ts) shared by the API, the agent skill, and the worker.
Database schema (D1)
The design→build bridge. Three locked structural decisions shape everything: surrogate user_id + identities table (claiming = INSERT an identity; pet rows are never rewritten), 1:1 hot pet_state row with typed columns + insert-only event/interaction logs (AI-tamago pattern), and balance column + insert-only coconut ledger (daily caps are ledger queries, not bespoke counters). Conventions: ids are TEXT uuids, timestamps are INTEGER epoch-ms, day columns are YYYY-MM-DD in the user's local timezone (caps, wishes, and streaks all reset at the user's 6am, computed in code from users.tz).
Identity & users
users
user_id TEXT PRIMARY KEY -- uuid
tz TEXT DEFAULT 'UTC' -- IANA, client-reported (see Time-of-day)
bedtime_hour INTEGER DEFAULT 22 -- sleep window start, local (8h fixed)
tier TEXT DEFAULT 'public' -- public | connected | gen3 | gen2_og
coconuts INTEGER DEFAULT 0 -- fast read; invariant: == SUM(coconut_ledger)
xp INTEGER DEFAULT 0 -- Adventure XP (level derived in mechanics.ts)
login_streak INTEGER DEFAULT 0
care_streak INTEGER DEFAULT 0
last_login_day TEXT
notif_prefs TEXT -- JSON toggles (bounded set, never queried)
push_sub TEXT -- web-push subscription JSON (standalone web)
created_at, last_seen_at INTEGER
identities -- (provider, external_id) → user
provider TEXT -- anon | tg | email | matrica
external_id TEXT -- device uuid | tg user id | email | matrica id
user_id TEXT REFERENCES users
created_at INTEGER
PRIMARY KEY (provider, external_id)
INDEX idx_identities_user (user_id)
Claim flow: anonymous hatch creates users + identities('anon', uuid); "save your monke" INSERTs ('tg', tg_user_id) or ('email', …) for the same user_id — zero rows rewritten, zero state moved. Matrica linking INSERTs ('matrica', …) and updates tier. XP lives on users, not pets, deliberately: shop unlocks are account progression and must survive lineage succession (a retired pet shouldn't re-lock the shop). Purge rule: users whose only identity is anon and last_seen_at > 90 days ago are deleted (cascade).
Pets & state
pets -- slow identity; lineage = this table's history
pet_id TEXT PRIMARY KEY
user_id TEXT REFERENCES users -- immutable owner
name TEXT
handle TEXT UNIQUE -- public profile /m/:handle
stage TEXT DEFAULT 'egg' -- egg | baby | teen | adult
hatched_at INTEGER
smb_mint TEXT -- pedigree parent NFT (NULL = none)
active_scene_id TEXT -- equipped Home background
active_frame_id TEXT -- equipped profile frame
retired_at INTEGER -- NULL = current pet; set = ancestor
INDEX idx_pets_user (user_id)
pet_state -- the hot 1:1 row
pet_id TEXT PRIMARY KEY REFERENCES pets
hunger, happiness, energy, hygiene REAL
last_interaction_at INTEGER -- the lazy-compute anchor
next_event_at INTEGER -- precomputed next threshold crossing
stat_zero_since INTEGER -- earliest "a stat is at 0" ts (coma 6h hold)
coma_since INTEGER -- NULL = not in coma
asleep_manual INTEGER DEFAULT 0 -- manual toggle (auto-wakes at energy 100)
awake_until INTEGER -- tap-to-wake session override
decay_pause_until INTEGER -- Cozy nap item
tone_override TEXT -- Moodifier register (sappy|manic|serene)
tone_override_until INTEGER
feed_cd_until, play_cd_until, clean_cd_until, free_salts_cd_until INTEGER
INDEX idx_state_next_event (next_event_at)
pet_interactions (insert-only) -- every care action / purchase-use / treat
id, pet_id, actor_user_id, kind, item_id, delta TEXT/JSON, ts
INDEX (pet_id, ts)
pet_events (insert-only) -- hatch | evolve | coma | revive | soul_arrived
id, pet_id, kind, detail TEXT/JSON, ts
INDEX (pet_id, ts)
There is no separate lineage table. The Profile's ancestor grid is pets WHERE user_id = ? AND retired_at IS NOT NULL, and "survived 2 comas" is pet_events — the append-only logs give lineage for free, which is exactly why we borrowed the pattern. The agent skill's 3 derived values come from one pet_state read (+ latest pet_events/pet_interactions row for last_event), cached in KV.
Economy & inventory
coconut_ledger (insert-only)
id, user_id
amount INTEGER -- + grants, − spends
source TEXT -- login | care | levelup | streak | visit |
-- visited | wishlist | purchase | revive
ref TEXT -- item_id / friend user_id / level no.
day TEXT -- user-local, for cap queries
ts INTEGER
INDEX idx_ledger_caps (user_id, day, source)
inventory
user_id, item_id TEXT -- catalog ids live in mechanics.ts
qty INTEGER -- consumables count; cosmetics qty=1
acquired_via TEXT -- shop | social_exclusive (7-day-streak frame)
PRIMARY KEY (user_id, item_id)
Every grant runs in one transaction: SELECT SUM(amount) … WHERE user_id=? AND day=? AND source=? against the cap from mechanics.ts → INSERT ledger row + UPDATE users.coconuts. The earn-caps table in Coconut economy (Plan tab) maps 1:1 to source values. The shop catalog itself is config, not DB — items/prices/level-gates stay in mechanics.ts so retuning never migrates.
Social, wishes & notifications
friendships -- one row per pair, canonical user_a < user_b
user_a, user_b TEXT
kinship REAL DEFAULT 0 -- 0–100; tier derived (25/60) in code
mutual_streak_days INTEGER DEFAULT 0
last_visit_ab_day, last_visit_ba_day TEXT -- 1/day enforcement + reciprocity nudge
created_at INTEGER
PRIMARY KEY (user_a, user_b)
visits (insert-only)
id, visitor_user_id, host_pet_id
is_gallery INTEGER DEFAULT 0 -- Discover visit (no kinship, smaller reward)
collected_at INTEGER -- NULL until owner collects the treat
day TEXT, ts INTEGER
INDEX (host_pet_id, collected_at) -- "2 friends left treats" banner
INDEX (visitor_user_id, day) -- daily visit caps
daily_wishes
pet_id, day TEXT
wish1_kind, wish2_kind TEXT -- from the mechanics.ts wish pool
wish1_done, wish2_done INTEGER DEFAULT 0
rewarded INTEGER DEFAULT 0 -- +10 🥥 paid exactly once
PRIMARY KEY (pet_id, day)
notification_log (insert-only)
id, user_id, type, day, ts -- care_nudge | treat | coma | evolution | revive
INDEX (user_id, day, type) -- max-1/day nudge + exactly-once per event
The threshold worker checks notification_log before sending (idempotency: one row per fired event, one care nudge per user-day). Kinship decay (−1/day) is applied lazily on friendship read, same pure-function trick as pet stats — no cron iteration over pairs.
Hot paths (the queries the schema is shaped around)
| Path | Queries |
|---|---|
| Home open | identities → users → current pet (retired_at IS NULL) + pet_state + uncollected visits + today's daily_wishes — 1 batched D1 call, state advanced in code. |
| Care action | One txn: UPDATE pet_state (+ new next_event_at), INSERT pet_interactions, capped ledger grant, wish progress check. |
| Agent skill (per message) | KV snapshot (TTL ~60s) → on miss: identities('tg') → pet + state + last event. Read-only. |
| Threshold cron | WHERE next_event_at <= now (indexed) → notify via notification_log guard → recompute. |
| Visit | INSERT visits, UPSERT friendships (kinship/streak), capped ledger grants both sides. |
| Claim / link | INSERT into identities (+ tier update if Matrica). Nothing else moves. |
identities(provider='tg'). The openclaw repos weren't available on this machine when this schema was designed — confirm its actual user table/key (and that table-name prefixes don't collide; if they do, prefix ours mg_*) before the first migration file.AI-tamago reference — what we borrow vs skip
Repo: ykhli/AI-tamago. We don't fork. Their stack (Next.js + Supabase + Inngest + Clerk) doesn't match ours. What's worth copying are a few patterns; most of the code is over-engineered or single-tenant by construction.
Borrow
| Pattern | Where they do it | How we use it |
|---|---|---|
| Append-only event-sourced status | supabase/migrations/...init_tables.sql — tamagotchi_status + tamagotchi_interactions are insert-only; current = latest row | D1 tables pet_status_log and pet_interactions insert-only, keyed by chat_id. Free history for LLM prompts. |
| Two-tier split: deterministic tick + LLM narration | They put stat math in the LLM (anti-pattern, see below). We invert: math in code, narration in LLM | Decay is a pure TS function evaluated on read (see State advancement — no cron mutation). Separate cheaper LLM call writes a single "thought" line, cached in KV with TTL. |
| Strict JSON output prompts | src/app/utils/state.ts:42-88 — they repeat "ONLY JSON" 3+ times | Same trick for any structured LLM output we add (e.g., portrait-prompt generation). |
| Preference vector memory (optional, v1.5) | src/app/utils/memory.ts + pgvector + Xenova transformers | If we add "remember what foods this monke liked," use Cloudflare Vectorize + small embeddings. Skip for v1. |
Skip / avoid
- LLM as physics engine. They ask GPT to compute new stat values every 5 min. ~288 calls/pet/day, expensive, non-deterministic, hard to balance. We do all decay/mood/stage math in pure TypeScript (testable, free, instant) and only call the LLM for narration.
- Inngest + waitForEvent ceremony. Over-engineered on CF Workers — just
awaitinline. - Module-level mutable state.
let status = ""at the top of route files — breaks on serverless cold starts and across users. We key everything bychat_idfrom day one. - Single-tenant schema. Their DB has no
user_idanywhere. Our schema hastg_user_idas primary key on every table. - Their stage / evolution system. Doesn't exist in code (just an unused
agecounter). We're building our own (see Game mechanics in Plan tab). - Their death system. Also doesn't exist — just a line in the prompt that says "you die when…" with no code to enforce it. We have explicit coma + revive.
- Their
interact/route.ts. Their team flagged it as messy; don't read for ideas.
Files worth a direct read in their repo
src/app/utils/state.ts— the whole update loop, ~120 LOCsupabase/migrations/20231029050944_init_tables.sql— schema in 30 linessrc/inngest/functions.ts— tick shape (port to CF Cron)
Other OSS references reviewed
AI-tamago was the LLM-integrated option, but we surveyed the broader virtual-pet OSS landscape too. Below: what we read, what we'll mine from each, what to skip.
| Repo | Stack | Why we'd read it | Verdict |
|---|---|---|---|
| Ido-Levi / claude-code-tamagotchi 423★ · MIT · active |
TypeScript hook for Claude Code statusline | Best modern example of "external event → deterministic stat delta → sprite." Exactly the pattern we chose; copy the event-source shape. | Read |
| trevarj / termagotchi 76★ · GPL-2.0 · stale |
Rust + TUI (tui-rs) | ~200-line Rust state machine covering the FULL Gen1 loop (hunger, discipline, age, poop, death). Mechanics AI-tamago skipped. Read src/pet.rs. |
Read for design (GPL — can't copy code) |
| GMMan / tama-para-research 80★ · no license · active |
Python + reverse-engineering notes | Tables of evolution branches, care-mistake counts, hidden stats from modern Tamagotchi (Smart / Uni / Paradise). Authoritative schema reference. | Read |
| aavegotchi / aavegotchi-contracts 325★ · MIT · active |
Solidity (Diamond) + Hardhat | Production on-chain Tamagotchi-like. Mine the stat schema (NRG/AGG/SPK/BRN/EYS/EYC), kinship-decay-as-mechanic, and trait-driven rarity. Ignore the chain layer. | Read data model (skip code) |
| blairjordan / codachi 215★ · MIT · active |
TypeScript · VS Code extension | Cleanest small codebase implementing real evolution stages (egg → baby → teen → adult) + sprite swap + persisted XP. Mine the stage-transition state machine and sprite manifest format. | Read |
| aptos-labs / aptogotchi 37★ · no license · stale-but-complete |
Next.js + Move (Aptos) | Cleanest small-scale "pet state on a backend you don't trust" example. Energy/happiness math, feed/play actions, body-part composition. Good mirror for comparing our D1 design. | Skim if curious |
| jcrona / tamalib 261★ · GPL-2.0 · active |
C — 6502-derivative CPU emulator | Authoritative source of truth for what the original 1997 mechanics actually were (timings, evolution paths, care-miss thresholds). Pair with tama-para-research. |
Reference only |
| Captain-Code / monagotchi 15★ · MIT · active |
C++ (ESP32) + TS agent + Monad chain | "External event → agent skill → pet stat delta" pattern with clear AI-layer/physics-layer separation. Worth skimming the boundary if we add external signal ingestion (e.g., $SOL price → pet mood). | Skim |
| blindbandit76 / virtual_pet 59★ · MIT · active |
Godot / GDScript · desktop | Art-pipeline reference — idle/eat/sleep/sick sprite frames organized cleanly. Useful template for our overlay manifest. | Skim if doing sprite work |
Top three to actually read
- Ido-Levi / claude-code-tamagotchi — the pattern we chose, in action. Best validation that "deterministic stat + ambient event source" works.
- trevarj / termagotchi + GMMan / tama-para-research — together: complete + correct mental model of classic Tamagotchi mechanics that AI-tamago missed.
- aavegotchi-contracts — best-in-class stat schema, kinship decay, trait-as-identity. Ignore the chain, steal the data model.
Risks + mitigations
- Image-gen style drift between pets — strict reference image + prompt template; manually review first 50 pets.
- Telegram Mini App iOS webview quirks — test on real iPhone early; lean on
@tma.js/sdkviewport helpers. - Threshold-cron scale —
next_event_atis indexed, so the cron touches only pets with due events (no global iteration); anon pets idle >90d are purged. - Agent persona inconsistency — snapshot-test prompt assembly against canned pet states.
- Empty cold-start — 60s hatching cinematic + immediate first DM.
Verification plan
- Hatch flow (non-Web3): open mini-app → name pet → see hatching → portrait in ~5s → first agent DM lands.
- Care updates agent tone: feed=happy=enthusiastic; neglect=grumpy=snippy. Snapshot-test prompt assembly.
- Evolution: fast-time multiplier in dev → stage transitions + new portrait + vocabulary expands.
- Coma + revive: neglect → sick visuals → mourning tone → revive → lineage records episode.
- Matrica pedigree: Gen2/Gen3/none each set correct tier, visuals, agent voice.
- Three entry paths: (a) anon web → email-claim merges. (b) Pet-first → BotFather wizard → skill enabled with existing pet_id. (c) Agent-first →
/hatch→ soul-arrived event → next reply has the "I feel different" moment. - Social: two test accounts visit each other; rate-limit holds.
- Cross-platform parity: all flows pass on mobile Safari + Chrome.
- State advancement is pure: redeploy mid-cycle → recomputed state identical, no double-decay; threshold worker fires each due event exactly once (idempotent on
next_event_at).
Monkegotchi — Hi-fi Mockups
ChatGPT-generated hi-fi screen mockups, one round at a time. Prompts live alongside this doc in .share/hifi-mockup-prompts.md; images drop into .share/mockups/ as they're generated, so this page is always the shareable, up-to-date view for the team.
Round 1 · core v2 screens
Direction B (Soft Illustrated Plush) on the main loop, Direction D (Vector Toon) as a gut-check on identity/social screens.
Hatch

Mobile app UI screen mockup, portrait phone aspect ratio, single cohesive screen like a Dribbble shot. Style: hand-drawn painterly illustration, soft watercolor textures, gentle outlines, warm and elegant — a premium mobile app aesthetic, not a children's storybook. Color palette: warm cream and tan (#f4e4d4, #c89568, #d4a374) with soft sage green accents (#7ba87b) and deep charcoal-navy text (#3a3a4e). Background: painterly dawn scene, warm gradient sky, minimal and uncluttered. Layout, top to bottom, centered narrow column: - Small centered title text at top: "Monkegotchi" - Large hero illustration, centered: an egg with a warm peach-to-tan gradient shell, painterly style, resting on a simple soft surface - Small italic caption below the egg: "tap the egg to crack it open" - A rounded input field with placeholder text: "name your monke" - A solid rounded pill button below it, cream text on warm tan fill: "Hatch ✨" - Small plain text line below the button: "🍌 Hold a MonkeDAO NFT? Link to unlock pedigree" - Smaller, lower-opacity plain text line at the very bottom: "Continue an existing monke →" Overall mood: warm, polished, premium mobile app onboarding screen — restrained and elegant, not whimsical or storybook. Flat UI elements (input, button) rendered in a soft rounded card style consistent with the painterly background, not photorealistic.
Home

Mobile app UI screen mockup, portrait phone aspect ratio, single cohesive screen like a Dribbble shot. Style: hand-drawn painterly illustration, soft watercolor textures, gentle hand-drawn outlines, Studio Ghibli inspired, cozy tender mood. Color palette: warm cream and tan (#f4e4d4, #c89568, #d4a374) with soft sage green accents (#7ba87b) and deep charcoal-navy text (#3a3a4e). Background: soft painterly daytime scene — warm daylight, gentle gradient, cozy outdoor or nest setting the pet lives inside. Layout, top to bottom, centered narrow column: - Top row: left side small rounded chip with text "Banana · 3d", right side a small bell/notification icon with a red badge showing "2" - Large hero illustration, centered: a small painterly baby monkey character, plush rounded silhouette, big expressive eyes, warm tan/cream fur, sitting in the scene - Below the pet, a rounded progress bar labeled "Adventure 7" with the bar mostly filled, showing "14/30 ⚡" at the end - Below that, centered italic text in quotes: "a little hungry — maybe play soon", with a smaller line underneath in lighter text: "— Banana's mood, tap → open chat" - A small centered pill/box with text: "✨ today: ☐ a cake · ☑ visit a friend → +10 🥥" - A highlighted sage-accented pill below it: "🎁 2 friends left treats — tap to collect (+10 happiness)" - A row of 4 equal rounded square icon buttons, solid tan fill: a banana icon, a ball icon, a soap/bubble icon, a crescent moon/sleep icon - Bottom row: left side bold currency text "🥥 73", right side small lighter text "Lvl 7 · 14XP to next" Overall mood: warm, cozy, alive steady-state pet-care home screen. Flat UI elements (bars, chips, buttons) rendered in a soft rounded card style consistent with the painterly background, not photorealistic.
Profile

Mobile app UI screen mockup, portrait phone aspect ratio, single cohesive screen like a Dribbble shot. Style: bold vector toon illustration, thick black outlines, flat fills, limited 5-color palette of warm brown (#a16207), pale sunny yellow (#fde68a), amber (#f59e0b), black (#000000), and a red accent (#dc2626). Simple expressive black dot eyes, slightly off-balance asymmetric shapes, modern indie sticker-pack style, Cult of the Lamb inspired. Background: flat warm cream/amber gradient, minimal. Layout, top to bottom, centered narrow column: - Top row: left side a simple back-arrow icon "←", center bold title text "Banana", right side a share/arrow-out icon "↗" - Large centered hero illustration: a bold vector-toon baby monkey character, thick black outlines, flat warm-brown and yellow fill, big simple dot eyes - Below the character, small centered caption text: "Baby · 3 days ·" followed by a small rounded badge/chip reading "Gen2 OG" - Below that, a small line of text: "👤 @jp.bedoya · MonkeDAO ✓" with a checkmark - A left-aligned small section label: "Lineage · 2 ancestors" - A 2x2 grid of 4 small rounded cards below it: - card 1: small circular character portrait, text "Mango · 12d", smaller text "survived 1 coma" - card 2: small circular character portrait, text "Coco · 9d", smaller text "retired" - card 3: a dark silhouette/shadow circle, text "???", smaller text "future" - card 4: a dark silhouette/shadow circle, text "???", smaller text "future" - A solid bold pill button below the grid, black text on amber fill: "Share · /m/banana" - A bottom navigation bar with 4 items: "Home", "Profile" (highlighted/active), "Friends", "Shop" Overall mood: bold, playful, iconic identity/profile screen. Flat UI elements (chips, cards, nav bar) rendered with the same thick black outlines and flat color fills as the character illustration, not photorealistic.
Friends

Mobile app UI screen mockup, portrait phone aspect ratio, single cohesive screen like a Dribbble shot. Style: bold vector toon illustration, thick black outlines, flat fills, limited 5-color palette of warm brown (#a16207), pale sunny yellow (#fde68a), amber (#f59e0b), black (#000000), and a red accent (#dc2626). Simple expressive black dot eyes, slightly off-balance asymmetric shapes, modern indie sticker-pack style, Cult of the Lamb inspired. Background: flat warm cream/amber gradient, minimal. Layout, top to bottom, centered narrow column: - Top: a rounded search bar with placeholder text "🔍 search monkes" - Below it, a row of 3 tabs: "Friends" (bold, highlighted/active fill), "Discover", "Visits" - A highlighted amber banner strip: "🎁 Solana_kid left Banana a snack — visit back ↩" - A 2-column grid of 6 small rounded character cards below: - card 1: small bold vector-toon monkey portrait, name "Banana_Jr", status "😊 · 💛BF", small text "✓ visited today" - card 2: small bold vector-toon monkey portrait with a highlighted outline border, name "Solana_kid", status "😴 · 💚Fr", small text "visit back ↩" - card 3: small bold vector-toon monkey portrait, name "MonkeBro", status "🍌 · 💚Fr", small text "visit" - card 4: small bold vector-toon monkey portrait, name "Pixel_Ape", status "😠 · 🤍Acq", small text "visit" - card 5: small bold vector-toon monkey portrait, name "OG_Legend", status "✨ · 💛BF 6🔥", small text "visit" - card 6: a dashed-outline empty card with a plus icon, text "+ invite a friend" - A bottom navigation bar with 4 items: "Home", "Profile", "Friends" (highlighted/active), "Shop" Overall mood: bold, playful, social collection/roster screen — like a sticker album. Flat UI elements (search bar, tabs, cards, nav bar) rendered with the same thick black outlines and flat color fills as the character illustrations, not photorealistic.
Empty frames above mean the image hasn't been dropped in yet — save each ChatGPT output as the filename noted under it, in .share/mockups/.














