The companion
Luna is a proper noun. There is one spirit, called Luna, and it wears different forms. A form is only an image you feel close to: every form has the same memory, the same coaching and the same history.
The fifteen forms
The painted forms are drawn live on the device in a 90s anime cel style. Four are available from the start. The rest become wearable as Luna’s level rises.
| Form | Name | Wearable from |
|---|---|---|
| Owl | Archimedes | always |
| Cat | Salem | always |
| Raven | Corvus | always |
| Wisp | Lumen | always |
| Fox | Ember | level 2 |
| Ferret | Zephyr | level 2 |
| Woodpecker | Rune | level 3 |
| Husky | Frost | level 3 |
| Australian shepherd | Merle | level 4 |
| Crane | Grus | level 5 |
| Monkey | Momo | level 6 |
| Bear | Bruin | level 7 |
| Mantis | Kaji | level 8 |
| Tiger | Rajah | level 9 |
| Fairy | Pip | level 10 |
The onboarding carousel shows every form. After that, ⋯ → Wear a different form opens the switcher (“Same luna, same memory — only the shape changes.”). Locked forms stay visible, dimmed and labelled with their level. Tapping one shows “Name awakens at level N — keep the streaks alive.” Switching reuses the avatar record for that form if one exists and creates it the first time. Nothing is re-bound and no history changes.
A custom avatar is a set of uploaded video loops, one per state (idle, listening, thinking, speaking). An idle loop is required, and any missing state falls back to idle.
How Luna changes over time
Three separate signals shape the drawing. Each one answers a different question.
| Signal | Driven by | What you see | Can it fade? |
|---|---|---|---|
| Vitality | The habit score | A leaner, quicker, more alert creature | Yes. A lazy month softens the body. |
| Majesty | Level (level ÷ 10) | Particles and aura | No. Levels never revoke. |
| Evolution stage (0–3) | Walking traits plus level, computed on the server | The drawing itself sharpens | No. |
The server owns the stage ladder (habit.AvatarStage), and the app only
renders it:
| Stage | Requires |
|---|---|
| 1 | Wayfarer trait level 1 or higher |
| 2 | Wayfarer 2, Strider 1, and Luna level 4 |
| 3 | Wayfarer 4, Strider 3, and Luna level 7 |
As the stage rises, the ink line thickens, a double contour appears, a second cel-shadow plane and a hard rim light are added, and at stage 3 there are ink flashes while Luna speaks or reasons. The Steps card shows the cheapest missing requirement for the next stage in your own units, for example “7 good step days → next form”. See Levels, traits and skills.
Six aspects, one Luna
Every reply comes from one of six aspects. You never pick one; you just ask. Luna chooses the aspect inside the same model call (the reply opens with a hidden tag that the server strips out), so routing costs no extra inference. The creature is tinted by the aspect’s colour, and each reply also carries the aspect’s name and icon, so colour is never the only cue.
| Aspect | Domain | Its limits |
|---|---|---|
| Counsel (default) | Business and personal decisions, strategy, brainstorming | Not a lawyer, accountant or financial adviser. Never moves money or commits you to anything. |
| Trainer | Training, workouts, form, recovery | Not a doctor or physio. For pain, numbness or a suspected injury, it says to stop and see a professional first. |
| Nutritionist | Meals, macros, hydration, plan adherence | Not a clinician. No diagnosis, supplements, medication, extreme restriction or rapid-loss protocols. Never assists disordered eating. |
| Keeper | Agenda, scheduling, day planning | No calendar, mail or messaging is connected. It can advise, but it never claims to have read, created or moved anything, and no reminder will fire. |
| Muse | Creative work, writing, design, music, naming | Original work only: no song lyrics or substantial copyrighted passages. |
| Naturalist | Animals: species, behaviour, care, identification | Not a vet. For illness, injury or poisoning, it says to contact a vet first. |
These limits are written into the prompt. They are advisory: they shape the reply but don’t constrain the process. What is enforced in code is data minimisation. Before the model runs, the server decides which of your data is put into the prompt, and each aspect declares what it may read:
| Aspect | Health journal, body and plans | Your “inner context” | Memory |
|---|---|---|---|
| Trainer, Nutritionist | yes | yes | yes |
| Counsel | no | yes | yes |
| Keeper, Muse, Naturalist | no | no | yes |
So a creative or animal question never has your health journal in its prompt.
“How I got here”: reasoning boxes
While Luna works on something, progress appears as small comic dialogue boxes
stacked beside the creature. These are not chat turns and are never saved.
Each box is a stable code from the platform’s step vocabulary (for example
STEP_ANALYSING or STEP_FOUND) plus facts the server actually observed. The
app writes the sentence. A code the app doesn’t recognise renders nothing, so
you never see a raw token. When the shared model is at capacity, Luna says so
instead of inventing a queue position.
The Dreamcore backdrop
Luna’s screen sits on a 90s liminal scene: telephone poles, an empty road, a water tower and VHS grain. It blends dawn, day, dusk and night from your clock. The profile, history and picker screens use a plain starfield instead.
Local weather is an opt-in connection on the profile page. When it is on, the scene mirrors the real sky (rain, snow, fog or storm). The weather is fetched by the app itself from Open-Meteo, with your location coarsened to about 1 km. It never goes through Luna’s backend. Today this works in the web build only; the profile page says “a native path is on the roadmap”.