# Evolution

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

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

Evolution stages (typically 3–6) 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:
"egg → baby → teen → master".

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.
