# Figures: Moods and moves

> What a figure shows for each mood, how it reacts as one changes, its fourteen faces, and the moves it makes on demand.

Source: https://cesarvenzac.com/figures/docs/moods

*Live example on the page: States. Each shape takes a mood its own way.* Its source:

```tsx
// What each of an agent's states shows: its expression, the loop
// it moves in, and now and then a move.
const MOOD = {
  idle: { expression: "neutral", loop: "breathe" },
  thinking: { expression: "thinking", loop: "think" },
  working: { expression: "working", loop: "work" },
  happy: { expression: "happy", loop: "breathe", now: "pop" },
  trouble: { expression: "trouble", loop: "worry", now: "shake" },
  sleep: { expression: "sleeping", loop: "rest" },
};

// As it changes, a reaction, each shape playing it its own way.
reactionTo("working", "happy"); // "celebrate"
reactionTo("idle", "sleep"); // "doze"

// A loop that turns something comes home every few seconds and
// stops only there, so the next never starts from a jump.
act.stop ??= stopFor(act, now, shape, speed);
```

A figure shows what its agent is doing through `mood`, one of six:

- `idle`: waiting. It breathes, blinks, glances about and does its habit now and then.
- `thinking`: setting up. It looks up and aside, and the cube scrambles and solves itself like a Rubik's cube.
- `working`: at work, its eyes narrowed and scanning, each shape busy its own way: the cube's layers tick like clockwork, the cloud rains.
- `happy`: done, something to look at. Happy eyes, and now and then it turns into a star.
- `trouble`: in trouble. Squeezed eyes, worrying, shaking now and then.
- `sleep`: switched off. Eyes shut, grey and dim, z's drifting off; it doesn't follow the pointer or answer a pet.

## Reactions

As the mood changes it reacts, each shape its own way:

- Into `happy`, it celebrates: the cube bursts and snaps back, the sphere splashes, the pyramid launches its capstone, the block spins its dials like a slot machine, the cloud gets a rainbow.
- Into `trouble`, it fails: its eyes cross and its colour drains.
- Into `thinking` or `working` from anything else, it gets going.
- Into `sleep`, it dozes off, yawning as its lids close; out of it, it wakes with a stretch.
- From `happy` back to `idle`, a nod: what it finished has been seen to.

When one celebrates, fails or is petted, the other figures on the page turn to look. `reactionTo(from, to)` says which reaction a change plays, for anything else that should follow along.

## Faces

*Live example on the page: Faces. Pick a face to hold it.* Its source:

```tsx
// A face is a few numbers: where the upper lid cuts each eye at
// its inner and outer side (li, lo), a lower lid rising in an
// arc (smile), the eyes' size and gaze, and the head's turn.
const FACES = {
  neutral: { glyph: "rect", li: 0, lo: 0, size: 1 },
  sad: { glyph: "rect", li: 0.05, lo: 0.5, pitch: -14 },
  thinking: { glyph: "rect", li: 0.2, dx: 0.045, yaw: 14 },
  love: { glyph: "heart", size: 1.15, pitch: 6, roll: -4 },
  failed: { glyph: "cross", pitch: -10, roll: -6 },
  // …fourteen in all
};

// Every frame the face eases toward the next, number by number,
// and a new glyph is blended in over a sixth of a second.
for (const key of FACE_KEYS) {
  face[key] += (goal[key] - face[key]) * k;
}
glyphMix = Math.min(1, glyphMix + dt * 6);
```

Fourteen expressions (`EXPRESSIONS`): neutral, happy, sad, tired, thinking, working, listening, speaking, sleeping, surprised, trouble, love, excited and failed. Each sets the eyes' lids, size and gaze and how the head is held, and some turn the eyes into a shape. A mood picks one; `expression` holds one whatever the mood:

```tsx
<AgentFigure figure={ada} expression="listening" />
```

Listening, its eyes swell as if to a voice; speaking, they bob; working, they scan.

## Moves

*Live example on the page: Moves. The same move at three energies.* Its source:

```tsx
// Every move is a pose as a function of time, from 0 to 1: a
// crouch before a hop, the hop, and a squash as it lands.
const pose = moveAt("hop", p, shape, energy.amp);

// Energy scales them all: how far each goes, and how long it
// takes.
const ENERGY = {
  calm: { amp: 0.65, speed: 1.3 },
  lively: { amp: 1, speed: 1 },
  bouncy: { amp: 1.35, speed: 0.82 },
};
const duration = ONCE_FOR[move] * ENERGY[energy].speed;
```

`play` makes a move now, and again each time its `at` changes:

```tsx
const [play, setPlay] = useState<{ motion: Once; at: number }>();
const spin = () => setPlay({ motion: "spin", at: Date.now() });

<AgentFigure figure={ada} play={play} />
<button onClick={spin}>Spin</button>
```

The moves (`MOVES`): hop, bounce, spin, turn (round to its next face), flip, nod, shake, wave (a wobble), pop (a star for a beat), melt (a blob) and love (a heart). The reactions play the same way (`REACTIONS`: pet, celebrate, fail, start, doze, wake). Every move is a pose worked out from time alone, a crouch before a hop and a squash as it lands, and `energy` scales them all.

## Looking and walking

On a desktop a figure turns toward the pointer, head and eyes (`look`, on unless set to `false`). `aim` sets where it looks instead, from −1 to 1 each way, right and down: at whoever it's talking to, say; only another figure's moment turns it away. `lift`, a function of the frame's time giving 0 to 1, hops it off the ground as it walks, its shadow staying put; it's read every frame, so it can follow a walk without a render.

## Petting and turning

Clicked, a figure is petted, heart eyes and hearts, and the link or button it's in doesn't open (`pet`, on unless set to `false`). With `grab`, dragging it turns it round, and it springs home when let go. Hovering the link or button it's in, or anything marked `data-figure-host`, makes it smile with a small bounce, once in 2.5 seconds at most (`react`).

## Figures's docs

- [Overview](https://cesarvenzac.com/figures.md): Small 3D figures for your agents, saying what each is doing with two eyes and the way they move.
- [Getting started](https://cesarvenzac.com/figures/docs/getting-started.md): Install Figures, put a figure beside an agent's name, and keep the four choices a figure is made of.
- [Moods and moves](https://cesarvenzac.com/figures/docs/moods.md): What a figure shows for each mood, how it reacts as one changes, its fourteen faces, and the moves it makes on demand.
- [Colours and stills](https://cesarvenzac.com/figures/docs/colours.md): Its eight colourways or colours of your own, your design tokens included, a dot of its colours, and a still for anywhere a live figure can't go.
- [API reference](https://cesarvenzac.com/figures/docs/api.md): Everything the package exports, entry by entry: the figures as data, and the React components with every prop.
