Each mood moves the lids, the brows, the cheeks and the colour together, the way a face does. Purple is the research accent from the palette, so it marks attention; orange stays for insight, warmth and heat. Click one to hold it on the stage.
Attention travels round the four lenses, one window at a time: set up, confirm, processing, output. The lit lens leans out, the iris jumps to it, the lids narrow in focus and the pupil widens under load. On the stage a ring tracks progress, and the lens that reads a source ripples. With reduced motion it keeps the light but holds every piece still.
One .riv file plays the same on web, iOS, Android and React Native. The app sets a few View Model properties; the file owns every pose, transition and timing. This page is the behaviour reference for it.
| state machine layer | states |
|---|---|
| intro | assemble → wake (lenses pop in, the eye opens with a double blink) → done |
| mood | neutral · curious · happy · surprised · focused · sleepy · annoyed · concerned · panic. Each one is a pose timeline for lids, brows, cheeks, axis and colour. |
| blink | open → blink, double, partial, or tight (poke). Randomised transitions set the rhythm; mood sets the speed. |
| gaze | additive blend of look left, right, up and down. It includes lid coupling, iris foreshortening and face parallax. |
| pupil | 1D blend: constricted → dilated |
| processing | idle → attention loop (four lenses in turn, progress ring, a document emitted per step) → done (ring closes, documents verified one by one) → idle |
| scenario | a timeline of actions; each action sets mood, reading, alarm, a glance, or emits a document (plain or flagged) |
| reflex | poke (a listener on the iris) → flinch; fast approach → startle |
| View Model property | type · who writes it |
|---|---|
mood | enum · app, or the brain script when auto is on |
auto | boolean · app: the script reads the pointer and picks the mood |
processing | boolean · app: an agent run starts or stops |
done · blink · intro | triggers · app |
gazeX · gazeY | number −1…1 · brain script (saccades, pursuit, drift) |
pupil | number 0…1 · brain script (light, mood, load, hippus) |
theme · reducedMotion | enum, boolean · app, from the platform |
step | number 0…3 · file → app: which window the spinner shows |
progress · documents | number 0…1, list of {type, title, status} · app: drives the ring and the lens ripples |
The brain is a Luau node script inside the file (its advance step runs every frame), so the eye behaves the same everywhere. If a target runtime does not run scripts, randomised blink transitions stay in the file and the app writes gazeX, gazeY and pupil instead.