# Rive Animator Brief β€” Lyra Avatar Emotion States **Ready-to-publish β€” copy section between the dividers below into your job-post on Dribbble / Fiverr / Twitter / Rive Discord.** --- ## 🎯 Project: Rebreak β€” Lyra Avatar Animation I'm hiring a Rive-animator to extend **Lyra**, the AI-companion of **Rebreak** β€” a recovery app for people working through gambling addiction (German market, planned DiGA-listing in healthcare). **Critical context:** This is a sensitive recovery-app, NOT a playful game. Lyra is a warm, present companion β€” never cute-mascot, never childish, never dramatic. Subtle > exaggerated. **Budget: $100 USD, ~1 week target.** Self-qualify before applying. ## What I have (current `.riv`) - File: `lyra-avatar.riv` (264 KB) β€” will be shared after engagement-confirmation - **Artboard name:** `Artboard` - **State machine name:** `State Machine 1`, default state `idle` - **Existing animation timelines** (extracted via `strings`): - `Idle Loop` β€” wired as `idle` - `idle to Pose 1` + `Pose 1 loop` β€” wired as `happy` (2-phase: app manually switches via 900ms JS-timer) - `01 Wave 1` β€” wired as `empathy` - `01 Wave 2` β€” exists, NOT wired (orphan) - `WALK` β€” placeholder, currently aliased as `thinking` (please replace with proper thinking-pose animation) - `Kedip` (Indonesian "blink") β€” orphan from template - **Runtime:** `rive-react-native ^9.0.1` (export against this compatible Rive editor version) - **Avatar usage:** appears at 40px (small list), 112px (chat-header), 160px (onboarding hero) β€” **must read clearly even at 40px** ## ⚠️ Critical naming contract β€” do NOT rename existing names The React code calls timelines **directly by name** (not via state-machine inputs). If you rename a timeline, the app silently breaks (no animation plays, no error). This means: - **Keep:** `Artboard` artboard, `State Machine 1` SM-name, `idle` default-state, `Idle Loop` timeline name - **New emotion-states must use exactly these timeline names** (snake_case): `sad`, `joy`, `confusion`, `calm`, `surprise`, `listening`, `thinking` (replacing `WALK`) - **For multi-phase emotions** (e.g. dramatic intro β†’ loop): use ` intro` + ` loop` pattern, just like existing `idle to Pose 1` + `Pose 1 loop` - **Bonus** (+$X if you propose): expose state-machine inputs (`SetEmotion` enum-trigger) so we can transition imperatively. Optional β€” named-timelines remain the primary contract. ## Deliverables β€” emotion states You'll add these to the existing state-machine. Total: **6 new states + 1 placeholder-replacement (`thinking`)**. ### Tier 1 β€” must-have (4 states, baseline budget) | Internal name (timeline) | Trigger in app | Eyes | Brow | Mouth | Body | |---|---|---|---|---|---| | **`thinking`** (REPLACE `WALK`) | LLM is generating response | look up-and-to-side, slow blink | one slightly raised | gently closed, slight pursed | finger-near-temple pose if possible, head tilt ~5Β° | | **`listening`** | User mid-typing OR voice-recording | open, attentive, natural blink | neutral relaxed | gently closed, micro-Mona-Lisa upturn | subtle head nod every ~3s | | **`calm`** | Breathing exercise / meditation active | half-closed | neutral relaxed | slight serene smile | very slow up/down breathing loop (~4s cycle to match 4-7-8 breathing pace) | | **`sad`** | User describes loss/relapse/shame | softened, slight downcast, lower lid raised | inner-up, slight angle | closed, neutral or micro-downturn | tiny head tilt down (~5Β°), slow breathing | ### Tier 2 β€” nice-to-have (2-3 more states, push budget if you can) | Internal name (timeline) | Trigger in app | Visual direction | |---|---|---| | **`joy`** | Streak milestone, big celebration | bigger smile than `happy` (warmer not goofy), small head bounce on intro then settle | | **`confusion`** | Lyra needs clarification | one brow raised, slight squint, head tilt ~10Β° to one side | | **`surprise`** | Unexpected user input | wide-open eyes (brief), both brows raised, small "o" mouth, quick head pull-back micro on intro then settle | ### Skip these (anti-patterns for recovery use-case) - ❌ `angry` / `frustrated` β€” never from coach - ❌ `shocked` / `horror` β€” too dramatic for trauma-context - ❌ Cute-mascot expressions (winks, tongue-out, hearts in eyes) - ❌ Heavy bone-rigs / particles β€” runtime cost too high ## Visual style guidelines - **Match existing Lyra-look** (extract palette + line-weight from the `.riv` you'll receive) - **Subtle is better** β€” these animations play during emotional moments, they should *support* not *demand* attention - **Loop-friendly** β€” `idle`, `calm`, `listening` should breathe naturally, no pop on loop boundary - **Smooth transitions** β€” prefer 200-400ms crossfades over hard cuts. Especially: `empathy β†’ idle β†’ happy` should never feel jarring (route through idle, never direct jump from negative to positive) - **Readability at 40px** β€” exaggerate eye/brow shapes slightly, avoid mouth-only emotion (mouth is too small at 40px to carry expression) ## Technical Requirements - **Output: ONE `.riv` file** named exactly `lyra-avatar.riv` (replaces current file) - **Single artboard, single state-machine** β€” preserve existing structure - **Rive editor version**: 2024.x (compatible with `rive-react-native ^9.0.1`) - **Performance**: 60 fps target on mid-range Android (Pixel 5-class) - **File-size**: ≀500KB (current 264KB, want headroom for new states) - **Loop-cycle precision**: `calm` should be ~4 seconds (we sync app-side to user's 4-7-8 breathing exercise) ## Bonus task (optional, +scope) Existing `happy` uses a 2-phase manual switch via 900ms JS-timeout β€” clunky. **If you can fix this so it loops cleanly inside the `.riv` itself** (intro auto-blends into loop without app-side coordination), that's worth +$X. ## Timeline + Budget - **$100 USD flat**, paid: 50% on first-draft approval, 50% on final delivery - **1 week** from brief-confirmation - **Milestones**: 1. Day 0: brief-confirm + you receive `.riv` file + answers to your questions 2. Day 2-3: first draft of 1-2 states for visual-direction approval (style-confirm) 3. Day 4-6: remaining states + 1 round of revisions 4. Day 7: final delivery ## Deliverables you provide 1. **`lyra-avatar.riv`** β€” replaces existing file 2. **Short README** (1 page max): - List of all timeline-names + when each plays - Any limitations or known issues - State-machine diagram (simple) 3. **Source-file** (Rive editor `.rev` or equivalent) for future edits 4. **Optional bonus**: short demo-video (15-30 sec) showing all states cycling β€” earns trust ## Questions to ask BEFORE starting (please answer in your application) 1. Can I use the current `.riv` as a base and add states, or do you want a clean rebuild? 2. Confirm Rive runtime version (`rive-react-native ^9.0.1`) β€” compatible with your export? 3. Should I also fix the existing `happy` 2-phase JS-timer (auto-blend in `.riv` instead)? 4. For the German market: any culture-specific gestures to avoid? 5. Any brand-colors / hex-codes I must match? 6. Audio cues or visual-only? 7. Do you have Figma / brand-guide I should reference? ## What I value in your work - Restraint over flashiness - Clean state-machine architecture (other devs may extend later) - Honest communication if scope is too tight for budget β€” happy to scope down to 4 states (Tier 1 only) - Async-first (Slack-like / email / Discord-DM) ## How to apply Send me: 1. Link to **Rive portfolio** (not Lottie, not After-Effects β€” actual `.riv` work) 2. **Confirmation you've read this brief** (so I know it's not auto-applied) 3. Your suggested approach: extend existing state-machine OR rebuild? 4. Your answers to the 7 questions above Looking forward to working together. --- **End of brief β€” copy everything above into your job-post.** ## How to use this brief (internal β€” not for animator) 1. **Vor dem Senden** alle `[Platzhalter]`-Stellen (insbesondere Communication-Channel falls du das spezifizieren willst) ausfΓΌllen 2. **Aktuelle `.riv` mitschicken** β€” Animator braucht sie als Style-Referenz + State-Machine-Setup 3. **Klarstellen**: Emotion-Namen in der Tabelle sind **Code-Contracts** und mΓΌssen exakt so im Rive-File heißen β€” sonst muss React-Code refactored werden 4. **Vor Vergabe** 2-3 Animator-Portfolios checken β€” suche β€žwarm/subtle character"-style, NICHT nur knallige Logo-Animationen 5. **Nach Erhalt der ersten Draft** auf echtem Android-Mid-Range-GerΓ€t testen (Pixel 5 oder Γ€lter), nicht nur iOS-Simulator 6. **Wo publishen** (in Reihenfolge der Wahrscheinlichkeit): - Rive Discord (https://rive.app/community β†’ Discord) β€” Rive-spezialisierte Animatoren, keine LottieFiles-Refugees - Twitter `#RiveAnimation` hashtag + DMs an Animator-Portfolios die du gut findest - Fiverr β€žRive animator" custom-offers ($30-150 typische Gigs) - Dribbble β€žHiring" section β€” gemischte Quality, mehr Style-fokus 7. **Wenn `.riv` ankommt**: drag in `apps/rebreak-native/assets/lyra-avatar.riv` (overwrite), commit, fertig. Code ist schon flexibel (RiveAvatar accepts any state-name nach Task #39 component-flex). ## Sources / Internal-Files - Brief-Audit: `apps/rebreak-native/components/RiveAvatar.tsx` (lines 42-51 β€” Emotion-API contract) - Existing `.riv`: `apps/rebreak-native/assets/lyra-avatar.riv` (264 KB) - Plugin: `apps/rebreak-native/plugins/with-rive-asset-android.js` (Android raw-resource auto-mirror) - Trigger-context: `apps/rebreak-native/app/lyra.tsx` (lines 37-44, 306-323), `apps/rebreak-native/app/urge.tsx`, `apps/rebreak-native/lib/lyraResponse.ts:57-61` (existing `detectEmotion()`)