States
States come in four groups, and every one is live below, sharing a single stage. On the default cute face each state has its own eyes, mouth and blush, and some throw off an effect (see Expressions); in line face mode each state also wears a mouth from STATE_MOUTH.
Resting
Attending
Feeling
Signalling
What a state defines
Body motion
A behaviour returns four numbers per frame — tilt, x, y and squash — which springs then chase. Because springs do the smoothing, a behaviour can jump its targets without producing a visible jump.
idle is the one worth reading:
Three sine waves at unrelated frequencies. Because the periods never line up, the motion has no perceptible loop — which is what stops a character sitting in a sidebar for ten minutes from looking like a repeating GIF.
Impulses
Some states need discrete events rather than a continuous curve. angry kicks the vertical spring every 1.8 to 3.2 seconds; listening nods. These add velocity directly instead of moving a target:
The spring absorbs the kick and settles, which produces a physical recoil that would be tedious to author as a curve.
Spring channels
Every continuous quantity is a damped spring integrated at a fixed 120 Hz substep, regardless of display refresh rate.
The fixed substep is why a 144 Hz monitor and a 60 Hz monitor converge identically. Integrating with the frame delta directly would make the character settle faster on a faster display.
Belt states on the cute face
On the eyes and line faces, sixteen states hand their body over to a belt overlay (STATE_BELT): the body morphs to a circle, shrinks to a core, and what the state means is carried by the elements moving around it. On the default cute face that would lose the face, so they do not shrink the body: the whole character, face included, stays, and the same meaning is said by an effect beside it (STATE_FX) — rising dots for thinking, a small filling bar at the top right for progress, a pencil for writing. powering-down dims the body and bouncing hops it.
Like the mood effects these are pure functions of time, carried on the snapshot as fx, so the vector, pixel and kaomoji series agree automatically. On the cute face snapshot.belt is always null.
Belts
The eyes and line faces draw these states with a belt: the body collapses to a core and the belt takes over. See belts and particles for how the transition works and how each belt is drawn. The demo below uses face="eyes" so the belts themselves are visible.
Belts are pure functions of time. Nothing accumulates, so a belt can be paused, scrubbed or resumed at any point and remain correct — which is what lets hundreds of characters be frozen without drifting out of sync when they resume.
At a glance
Every state in one table: the eyes it cycles, its mouth, its effect (cute face) or the belt it hands its body to (eyes and line faces), the protocol ids that reach it, and a dial that tends to sit well beside it. All but the last column are read from the engine's tables at render time; the HUD column is a suggestion, since a dial is data the host has and a state is what the agent is doing, and the engine deliberately keeps the two independent.
Resting
| State | Eyes | Mouth | Effect | Id | HUD | |
|---|---|---|---|---|---|---|
idleIdle | dot → dot → dot → dotLeft → dot → dotRight | none | — | 02 | — | |
sleepingSleeping | curve | none | zz | 00 | clock | |
drowsyDrowsy | curveSleepy → dotHalf → curveSleepy | none | zz | 0615 | — | |
boredBored | dotHalf → dotLeft → dotHalf → dotRight | flat | — | 04 | — | |
wakingWaking | curve → dotHalf → dot | dot | — | 0107 | — | |
powering-downPowering down | dot → dotHalf → curve | none | — | 41 | — |
Attending
| State | Eyes | Mouth | Effect | Id | HUD | |
|---|---|---|---|---|---|---|
listeningListening | dotLeft → dot → dotLeft | none | — | 3537 | — | |
thinkingThinking | dotLook → dotUp → dotLook | flat | dots | 30 | context | |
searchingSearching | dotLeft → dotRight → dotUp → dot | dot | — | 40 | — | |
readingReading | dotLeft → dotRight | none | — | 42 | — | |
writingWriting | dotDown → dot | none | pencil | 43 | — | |
workingWorking | dotDown → dot → dotDown | none | arc | 1632 | gauge | |
loadingLoading | dot → dotLook | none | spinner | 0536 | — | |
progressProgress | dot | none | progress | 47 | progress | |
radarScanning | dot → dotLeft → dotRight | none | ripple | 51 | — | |
orbitOrbiting | dot → dotLook | none | orbit | 49 | — | |
dictatingDictating | dotLeft → dot | o | waves | 46 | voice | |
uploadingUploading | dotUp → dot | none | rise | 45 | sync | |
sendingSending | dot → arch | smile | send | 44 | — | |
receivingReceiving | dotWide → dot | dot | fall | 31 | — | |
messagingMessaging | dot → arch | cat | bubbles | 52 | notify | |
waitingWaiting | dot → dotLeft → dot → dotRight | none | ellipsis | 48 | timer | |
spawningSpawning | dotWide → dot | dot | gather | 08 | — | |
composingComposing | dotDown → dot | cat | — | 39 | — | |
draggingDragging | dotRight → dot → dotRight | o | — | 09 | — |
Feeling
| State | Eyes | Mouth | Effect | Id | HUD | |
|---|---|---|---|---|---|---|
happyHappy | arch → archWide → arch | cat | heart | 10 | — | |
excitedExcited | dotWide → archWide | grin | — | 22 | — | |
laughingLaughing | archWide → arch | laugh | — | 23 | — | |
playfulPlayful | arch → wink → archWide → dot | smirk | — | 24 | — | |
proudProud | dotUp → arch | smile | sparkle | 19 | — | |
celebrateCelebrating | star → archWide → wink → arch | grin | sparkle | 2533 | kpi | |
bouncingBouncing | arch → dotWide | smile | — | 26 | — | |
shyShy | dotDown → dotHalf | cat | — | 14 | — | |
sadSad | sad | frown | tear | 12 | — | |
angryAngry | mad | frown | — | 21 | — | |
confusedConfused | dotSuspicious → dotLook → dotHalf | wavy | — | 1120 | — | |
suspiciousSuspicious | dotSuspicious → dotHalf | flat | — | 18 | — | |
surprisedSurprised | dotWide | o | strokes | 13 | — | |
scaredScared | dotWide → dotSmall | wavy | strokes | 17 | — | |
curiousCurious | dotWide → dotLeft → dotWide → dotRight | dot | — | 03 | — | |
hummingHumming | curve → dotHalf → curve → dot | smile | — | 27 | — |
Signalling
| State | Eyes | Mouth | Effect | Id | HUD | |
|---|---|---|---|---|---|---|
alertingAlerting | dotWide → dot | o | bang | 34 | — | |
notifyingNotifying | dotWide → arch → dot | dot | — | 50 | notify | |
refusingRefusing | cross → dotHalf | wavy | bang | 38 | — |
Mapping application state
Most applications do not think in these terms. Two helpers translate.
| tool | state |
|---|---|
search | searching |
web_search | searching |
grep | searching |
glob | searching |
browse | reading |
fetch | reading |
read_file | reading |
read | reading |
write_file | writing |
write | writing |
edit | writing |
str_replace | writing |
run | working |
shell | working |
bash | working |
terminal | working |
upload | uploading |
think | thinking |
plan | thinking |
ask | listening |
wait | waiting |
{ awaitingUser: true } | waiting |
{ running: true } | working |
Next
- Springs and states — channels, impulses and settling
- Belts and particles — how the
eyesandlinefaces hand the body to a belt