RIVE BUILD GUIDE
Documentation for Vitto
Vitto — Rive Editor Build Guide
Step-by-Step: From SVG to Animated .riv File
Estimated time: 2-4 hours for full build Prerequisites: Rive account (free tier works for building, Cadet+ for AI Agent)
Path A: Fastest — Rive AI Agent (Recommended)
Rive now has a built-in AI Agent that can generate state machines, layouts, shapes, and animations from prompts. This is by far the fastest path.
Setup
- Go to rive.app and sign in
- You need a Cadet, Voyager, or Enterprise plan for AI Agent access
- Create a new file
Workflow
Step 1: Import the SVG
- Drag
vitto-rive-import.svgonto the Rive editor canvas - All layers will appear in the hierarchy panel with proper names (ear_left, eye_right, whiskers, etc.)
Step 2: Use the AI Agent to scaffold everything Open the Agent panel (left sidebar) and use these prompts in sequence:
Prompt 1 — Artboard setup:
Rename the artboard to "VittoAvatar" and set its size to 260x280.
Set the background to transparent.
Prompt 2 — Create the state machine:
Create a state machine called "MoodController" with these inputs:
- Number input "moodIndex" (default 0)
- Number input "gazeX" (default 0)
- Number input "gazeY" (default 0)
- Number input "intensity" (default 1)
- Boolean input "isSpeaking" (default false)
Create 14 states named: neutral, focused, cheerful, empathetic, curious,
analytical, celebratory, apologetic, inspired, urgent, playful, confused,
proud, sleepy.
Create transitions from "Any State" to each mood state, with condition
"moodIndex == [index]" where neutral=0, focused=1, cheerful=2, empathetic=3,
curious=4, analytical=5, celebratory=6, apologetic=7, inspired=8, urgent=9,
playful=10, confused=11, proud=12, sleepy=13.
Set default blend time to 700ms with ease-in-out.
Prompt 3 — Create the neutral idle animation:
Create a timeline animation called "neutral_idle" that loops.
Duration: 8 seconds, 60fps.
Animate these properties:
- ear_left: rotate 5 degrees at 0.5s, return by 0.7s (sharp ear flick)
- ear_right: rotate 5 degrees at 3.0s, return by 3.2s
- head_main: subtle Y translation of -2px from 0-4s (breathing sine)
- The whole artboard should have a gentle floating feel
Link this animation to the "neutral" state in MoodController.
Then continue with similar prompts for each mood. See RIVE-PRODUCTION-SPEC.md Section 5.3 for the exact animation specs per mood.
Path B: Manual Build (No AI Agent)
Step 1: Create New File
- Go to rive.app/editor
- Click "New File"
- Click on the artboard name → rename to "VittoAvatar"
- Set artboard size: 260 x 280
- Set background to transparent
Step 2: Import SVG
- Download
vitto-rive-import.svgfrom this package - Drag the SVG file directly onto the Rive editor canvas
- The layers panel (left side) should show all named groups:
- tail, ears, head, goggles, headphones, scarf, blush, nose, eyes, eyebrows, mouth, whiskers
- Verify: Each group should be expandable with sub-elements
Troubleshooting: If gradients look wrong, Rive may not support gradient transforms. You can manually recreate fills using Rive's gradient tools.
Step 3: Set Up Bones (Critical for Animation)
Bones let you rotate/move connected parts naturally.
a) Ear Bones:
- Select the Bone tool (B key)
- Click on
ear_leftgroup - Place bone root at (68, 100) — ear base
- Place bone tip at (38, 18) — ear tip
- Repeat for
ear_right: root (192, 100), tip (222, 18)
b) Eye Bones (for pupil tracking):
- Create bone inside
eye_leftat (98, 136) - Bind
pupil_L,iris_L,shine1_L,shine2_L,shine3_Lto this bone - Repeat for
eye_rightat (162, 136)
c) Tail Bone:
- Create a bone chain along the tail path
- Root at (200, 240), mid at (248, 190), tip at (238, 155)
- Enable IK (inverse kinematics) for natural sway
d) Head Bone:
- Create bone at (130, 152) — head center
- Bind head, goggles, headphones, eyes, nose, mouth, whiskers, blush, eyebrows
- This allows head tilt rotation for all moods
Step 4: Create Constraints
Eye Gaze Constraint:
- Select the pupil bones
- Add a Translation Constraint driven by inputs
gazeXandgazeY - Set multiplier: X range = 5px, Y range = 4px
- This makes pupils follow the mouse
Eye Clip for Blinks:
- Select
eyeClipLellipse - The
ryproperty controls how "open" the eye is - Animate
ryfrom 22 (fully open) → 0 (fully closed) for blinks
Step 5: Create the State Machine
- Switch to State Machine mode (icon at top)
- Click "+" to create a new state machine → name it "MoodController"
Add Inputs:
| Click "+" in Inputs panel | Type | Name | Default |
|---|---|---|---|
| Number | moodIndex | 0 | |
| Number | gazeX | 0 | |
| Number | gazeY | 0 | |
| Number | intensity | 1 | |
| Boolean | isSpeaking | false |
Add States: 3. Right-click on the state machine graph → "Add State" 4. Create 14 states: neutral, focused, cheerful, empathetic, curious, analytical, celebratory, apologetic, inspired, urgent, playful, confused, proud, sleepy 5. Set "neutral" as the entry state (right-click → "Set as Entry")
Add Transitions:
6. From "Any State", drag a transition arrow to each mood state
7. Click each transition → add condition: moodIndex == [index]
- neutral:
moodIndex == 0 - focused:
moodIndex == 1 - ... etc.
- Set blend time: 700ms, easing: ease-in-out
Step 6: Create Animations (Per State)
For each of the 14 moods, create a timeline animation that loops:
- Switch to Animate mode
- Click "+" → name it (e.g.,
neutral_idle) - Set duration and loop behavior
- Add keyframes for the properties listed in
RIVE-PRODUCTION-SPEC.mdSection 5.3
Example: Neutral Idle (8s loop)
0.0s — ear_left rotation: 0°
0.5s — ear_left rotation: 5° (quick flick)
0.7s — ear_left rotation: 0° (settle)
3.0s — ear_right rotation: 5°
3.2s — ear_right rotation: 0°
4.0s — eyelid_L ry: 22→0→22 (blink, 400ms)
eyelid_R ry: 22→0→22 (blink, 400ms)
0-8s — head bone Y: sine wave, amplitude 2px (breathing)
0-8s — tail bone: gentle sway via IK
Link to State:
- In the MoodController state machine, click the "neutral" state
- Assign
neutral_idleanimation - Set to Loop
Repeat for all 14 moods using the specs in RIVE-PRODUCTION-SPEC.md.
Step 7: Color Transitions
For mood-specific colors, you have two approaches:
Option A: Rive View Model (Recommended)
- Create a View Model with color properties for each gradient stop
- Bind fills to View Model properties
- The Angular runtime updates colors per mood via
VittoMoodService
Option B: Separate Color Keyframes Per Animation
- In each mood's idle animation, also keyframe the fill colors
- The state machine blend handles the color transition automatically
- This is simpler but means colors are baked into the .riv file
Step 8: Export & Test
- Click File → Export → .riv (binary format)
- Save as
vitto-avatar.riv - Place in
apps/gograb-ai/src/assets/rive/vitto-avatar.riv - The
VittoRiveAvatarComponentwill load it automatically
Quick Test Without Full Build
If you want to see Rive in action immediately WITHOUT building the full character:
- Go to rive.app/editor
- Import
vitto-rive-import.svg(drag & drop) - Switch to Animate mode
- Create a quick "blink" animation:
- Keyframe
eyelid_Lopacity: 0 → 1 → 0 over 300ms - Keyframe
eyelid_Ropacity: 0 → 1 → 0 over 300ms
- Keyframe
- Hit Play — you'll see Vitto blink!
- This proves the SVG import works and you can start building from there
Resources
- Rive Editor — Web-based editor
- Importing Assets Guide — SVG import docs
- State Machine Guide — Beginner tutorial
- State Machine Docs — Full reference
- Rive AI Agent — AI-powered building (requires Cadet+ plan)
- @rive-app/canvas — Angular/Web runtime