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

  1. Go to rive.app and sign in
  2. You need a Cadet, Voyager, or Enterprise plan for AI Agent access
  3. Create a new file

Workflow

Step 1: Import the SVG

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

  1. Go to rive.app/editor
  2. Click "New File"
  3. Click on the artboard name → rename to "VittoAvatar"
  4. Set artboard size: 260 x 280
  5. Set background to transparent

Step 2: Import SVG

  1. Download vitto-rive-import.svg from this package
  2. Drag the SVG file directly onto the Rive editor canvas
  3. The layers panel (left side) should show all named groups:
    • tail, ears, head, goggles, headphones, scarf, blush, nose, eyes, eyebrows, mouth, whiskers
  4. 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:

  1. Select the Bone tool (B key)
  2. Click on ear_left group
  3. Place bone root at (68, 100) — ear base
  4. Place bone tip at (38, 18) — ear tip
  5. Repeat for ear_right: root (192, 100), tip (222, 18)

b) Eye Bones (for pupil tracking):

  1. Create bone inside eye_left at (98, 136)
  2. Bind pupil_L, iris_L, shine1_L, shine2_L, shine3_L to this bone
  3. Repeat for eye_right at (162, 136)

c) Tail Bone:

  1. Create a bone chain along the tail path
  2. Root at (200, 240), mid at (248, 190), tip at (238, 155)
  3. Enable IK (inverse kinematics) for natural sway

d) Head Bone:

  1. Create bone at (130, 152) — head center
  2. Bind head, goggles, headphones, eyes, nose, mouth, whiskers, blush, eyebrows
  3. This allows head tilt rotation for all moods

Step 4: Create Constraints

Eye Gaze Constraint:

  1. Select the pupil bones
  2. Add a Translation Constraint driven by inputs gazeX and gazeY
  3. Set multiplier: X range = 5px, Y range = 4px
  4. This makes pupils follow the mouse

Eye Clip for Blinks:

  1. Select eyeClipL ellipse
  2. The ry property controls how "open" the eye is
  3. Animate ry from 22 (fully open) → 0 (fully closed) for blinks

Step 5: Create the State Machine

  1. Switch to State Machine mode (icon at top)
  2. 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]

  1. 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:

  1. Switch to Animate mode
  2. Click "+" → name it (e.g., neutral_idle)
  3. Set duration and loop behavior
  4. Add keyframes for the properties listed in RIVE-PRODUCTION-SPEC.md Section 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:

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)

  1. Create a View Model with color properties for each gradient stop
  2. Bind fills to View Model properties
  3. The Angular runtime updates colors per mood via VittoMoodService

Option B: Separate Color Keyframes Per Animation

  1. In each mood's idle animation, also keyframe the fill colors
  2. The state machine blend handles the color transition automatically
  3. This is simpler but means colors are baked into the .riv file

Step 8: Export & Test

  1. Click File → Export → .riv (binary format)
  2. Save as vitto-avatar.riv
  3. Place in apps/gograb-ai/src/assets/rive/vitto-avatar.riv
  4. The VittoRiveAvatarComponent will load it automatically

Quick Test Without Full Build

If you want to see Rive in action immediately WITHOUT building the full character:

  1. Go to rive.app/editor
  2. Import vitto-rive-import.svg (drag & drop)
  3. Switch to Animate mode
  4. Create a quick "blink" animation:
    • Keyframe eyelid_L opacity: 0 → 1 → 0 over 300ms
    • Keyframe eyelid_R opacity: 0 → 1 → 0 over 300ms
  5. Hit Play — you'll see Vitto blink!
  6. This proves the SVG import works and you can start building from there

Resources