# Evolution

> Stages the buddy grows through over time — the Tamagotchi arc.

Source: https://docs.hatched.live/docs/concepts/evolution

Evolution stages (between 1 and 5 — 5 is the hard maximum) trigger when
conditions are met: total XP,
specific skill levels, badges earned, coin thresholds. Each stage gets a
new look.

## Why evolution exists

Evolution is the **long-horizon motivator**. Coins reward today. Streaks
reward this week. Evolution is the story that spans weeks or months:
"Hatchling → Fledgling → Juvenile → Adult → Elder". (The egg belongs to the
hatch ceremony — evolution stages are post-hatch, so stage 1 is the
just-hatched Hatchling, not an egg.)

The image pipeline regenerates the buddy's bare art at each stage. If the
buddy has marketplace items equipped, Hatched then renders those items over
the new `base_image_url` and reports that composite through
`buddy.appearance`.

## Example

> **Stage 2 unlocks at total XP ≥ 500 + "Streak 7" badge.** When met,
> `evolution.ready` fires. If auto-evolve is off, your backend calls
> `buddies.evolve(buddyId)` and `operations.wait` returns the new buddy
> stage in 5–20s. Check `buddy.appearance.status` to confirm whether any
> equipped items have finished rendering on the new stage.

## Runtime loop

Event ingestion reports readiness, but the stage transition is a separate
operation unless the customer's config has `auto_evolve` enabled:

```ts
const effects = await hatched.events.send({
  eventId,
  userId,
  type: 'lesson_completed',
});

if (effects.evolutionReady) {
  const op = await hatched.buddies.evolve(buddyId);
  await hatched.operations.wait(op.operationId);
}
```

With `auto_evolve: true`, Hatched starts that operation when readiness is
detected and still emits the `evolution.ready` webhook for observability.

## Appearance after evolve

Evolution commits the stage transition first. Item compositing is attempted in
the same operation, but a credit shortage or provider failure does not roll the
stage back. Instead, the buddy response exposes:

- `base_image_url` — the trustworthy bare image for the new stage.
- `image_url` — the current display image.
- `appearance.status` — `ready`, `pending`, `awaiting_credits`, or `failed`.
- `rendered_equipped_item_ids` — the item layers currently visible in
  `image_url`.

Widgets poll `/widget/state` and show the latest safe visual while a composite
is pending. For `failed` appearances with `error.code === 'needs_rerender'`,
call `buddies.rerenderAppearance(buddyId)` before re-equipping items.

## Modes

- **Preset** — a fixed set of 5 sprite stages per preset.
- **Generative** — AI-generated art per buddy at each stage. Slower, more
  unique.
- **Hybrid** — preset base with a generative overlay for personalised
  details.

## How to set it up

1. Pick an evolution model (preset / generative / hybrid).
2. Set conditions per stage (XP, skill level, badge, coin).
3. Pick a creature style (cute, sci-fi, fantasy, minimal).
4. Decide auto vs. manual evolve.

## Gotchas

- `evolution.ready` fires even if auto-evolve is off. In that mode, call
  `buddies.evolve(buddyId)` from your backend when you want to advance the
  stage.
- Generative mode takes 5–20s per stage; treat it as an async operation and
  use `operations.wait` or the widget's built-in loading state.
- Equipped marketplace items must work on all stages. Test early stage
  equipment against late stage art, and monitor `buddy.appearance` for delayed
  composites.

## Related

- [Compositing & stages](/docs/concepts/compositing-and-stages) — how items survive a stage change, and the `appearance` state machine.
- [Buddy & hatch](/docs/concepts/buddy-and-hatch) — where a buddy starts.
- [Skills](/docs/concepts/skills) — a common evolution trigger.
- [Customize buddy](/docs/guides/customize-buddy) — equip + evolve end to end.
