<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Praneeth Kawya Thathsara</title>
    <description>The latest articles on DEV Community by Praneeth Kawya Thathsara (@uianimation).</description>
    <link>https://dev.to/uianimation</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3302156%2F3e7d5c5e-ca56-4bff-99ae-0dd9a5cc16ed.png</url>
      <title>DEV Community: Praneeth Kawya Thathsara</title>
      <link>https://dev.to/uianimation</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/uianimation"/>
    <language>en</language>
    <item>
      <title>Building an AI Web App? Get a Custom Rive Avatar for Your AI Assistant</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Sat, 19 Sep 2026 21:05:11 +0000</pubDate>
      <link>https://dev.to/uianimation/building-an-ai-web-app-get-a-custom-rive-avatar-for-your-ai-assistant-4hdd</link>
      <guid>https://dev.to/uianimation/building-an-ai-web-app-get-a-custom-rive-avatar-for-your-ai-assistant-4hdd</guid>
      <description>&lt;p&gt;Your AI assistant can answer questions and speak. What should users see while they interact with it?&lt;/p&gt;

&lt;p&gt;For an AI tutor, voice assistant, or companion app, a custom animated avatar can communicate when the app is listening, preparing a response, or speaking.&lt;/p&gt;

&lt;p&gt;But creating that character introduces another set of tasks: illustration, rigging, expressions, mouth movement, animation transitions, and developer controls.&lt;/p&gt;

&lt;p&gt;That is the work I help teams with at &lt;strong&gt;Mascot Engine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I’m Praneeth, a Rive animator creating custom interactive mascots and AI avatar animations for web and mobile products.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Building an AI web app that needs an animated character?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Explore &lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt; and send me your app screenshot, platform, and avatar requirements.&lt;/p&gt;

&lt;p&gt;📧 &lt;a href="mailto:mascotengine@gmail.com"&gt;mascotengine@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💬 &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;WhatsApp: +94 71 700 0999&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Your app handles the conversation. The avatar shows its state.
&lt;/h2&gt;

&lt;p&gt;Imagine a language-learning app with an AI tutor.&lt;/p&gt;

&lt;p&gt;When the learner speaks, the character looks attentive. While the app prepares a response, the character moves into a subtle thinking animation. When response audio starts playing, its mouth moves with the speech.&lt;/p&gt;

&lt;p&gt;These behaviours need a clear connection to the application.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What happens in your app&lt;/th&gt;
&lt;th&gt;What the avatar could do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The session becomes available&lt;/td&gt;
&lt;td&gt;Settle into a friendly idle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The app accepts microphone input&lt;/td&gt;
&lt;td&gt;Show an attentive listening expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A response is being prepared&lt;/td&gt;
&lt;td&gt;Play a restrained thinking animation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response audio plays&lt;/td&gt;
&lt;td&gt;Animate the mouth and speaking expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The learner completes a task&lt;/td&gt;
&lt;td&gt;Play a short celebration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A connection fails&lt;/td&gt;
&lt;td&gt;Show a calm error reaction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is an example brief, not a fixed feature package. The right states depend on your product.&lt;/p&gt;

&lt;p&gt;The important design decision is to make the avatar reflect what the app is actually doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Rive for an interactive AI avatar?
&lt;/h2&gt;

&lt;p&gt;Rive state machines let you connect animations and define the logic for transitions between them. Your character can have different behaviours instead of playing the same animation continuously.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://rive.app/docs/editor/state-machine/state-machine" rel="noopener noreferrer"&gt;official Rive state machine documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rive also provides runtimes for web, React, Flutter, React Native, and other platforms. Feature support varies by runtime and renderer, so the implementation should be planned around your actual stack.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://rive.app/docs/runtimes/getting-started" rel="noopener noreferrer"&gt;Rive runtime guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a web developer, the goal is an animation asset with clearly documented controls that can be connected to application events.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can you commission from Mascot Engine?
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;, I provide custom Rive character animation services scoped around your product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Character design and preparation
&lt;/h3&gt;

&lt;p&gt;Already have a mascot illustration? I can assess how it should be prepared for animation.&lt;/p&gt;

&lt;p&gt;Starting with an idea? We can define a character direction around your interface, audience, and brand.&lt;/p&gt;

&lt;p&gt;The design should remain readable at its actual display size—not only in a large portfolio preview.&lt;/p&gt;

&lt;h3&gt;
  
  
  2D rigging and expressions
&lt;/h3&gt;

&lt;p&gt;A character rig makes it possible to animate the face and body consistently.&lt;/p&gt;

&lt;p&gt;Depending on the design, the scope can include eyes, eyebrows, mouth shapes, head movement, and gestures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activity animations and transitions
&lt;/h3&gt;

&lt;p&gt;We define the behaviours your app needs and how the character moves between them.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Idle to listening.&lt;/li&gt;
&lt;li&gt;Listening to thinking.&lt;/li&gt;
&lt;li&gt;Thinking to speaking.&lt;/li&gt;
&lt;li&gt;Speaking back to listening after an interruption.&lt;/li&gt;
&lt;li&gt;Any relevant activity to an error or fallback state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The transitions deserve attention alongside the individual animations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lip-sync controls
&lt;/h3&gt;

&lt;p&gt;A repeating talking loop, audio-driven mouth opening, and viseme-based animation are different deliverables.&lt;/p&gt;

&lt;p&gt;We agree on the approach before production, including what data your application will provide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer handoff
&lt;/h3&gt;

&lt;p&gt;The agreed deliverables can include the exported &lt;code&gt;.riv&lt;/code&gt; file, animation controls, state mappings, and implementation notes.&lt;/p&gt;

&lt;p&gt;The purpose is to give your developer a clear specification for operating the character.&lt;/p&gt;




&lt;h2&gt;
  
  
  Start with the avatar your first release needs
&lt;/h2&gt;

&lt;p&gt;You do not need to define every future expression before discussing a project.&lt;/p&gt;

&lt;p&gt;For an initial voice-based web app, I would consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A calm idle.&lt;/li&gt;
&lt;li&gt;An attentive listening state.&lt;/li&gt;
&lt;li&gt;A subtle thinking state.&lt;/li&gt;
&lt;li&gt;A speaking state with the agreed mouth controls.&lt;/li&gt;
&lt;li&gt;An error or fallback reaction.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additional expressions, celebrations, outfits, or growth stages can be scoped separately when they support the product.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Need help turning your app idea into an animation brief?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contact &lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt; with your app link or screenshot, existing artwork, and the interactions you need.&lt;/p&gt;

&lt;p&gt;📧 &lt;a href="mailto:mascotengine@gmail.com"&gt;mascotengine@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💬 &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;WhatsApp: +94 71 700 0999&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What stays in your application?
&lt;/h2&gt;

&lt;p&gt;A custom avatar needs a clear division of responsibilities.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Animation scope&lt;/th&gt;
&lt;th&gt;Application integration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Character artwork and rig&lt;/td&gt;
&lt;td&gt;AI model and conversation logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expressions and animated states&lt;/td&gt;
&lt;td&gt;Microphone permissions and input&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authored mouth shapes and controls&lt;/td&gt;
&lt;td&gt;Audio playback and timing signals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Animation transition logic&lt;/td&gt;
&lt;td&gt;Network status and request handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documented character controls&lt;/td&gt;
&lt;td&gt;Connecting app events to those controls&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The final split should be agreed for your project.&lt;/p&gt;

&lt;p&gt;For example, an animator can author a mouth-opening control. Your application still needs to supply values that correspond to the character’s speech audio.&lt;/p&gt;

&lt;p&gt;Rive data binding can connect application-controlled data to properties in the character scene. The exact View Model structure and property names should be documented for the authored file.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://rive.app/docs/editor/data-binding/overview" rel="noopener noreferrer"&gt;Rive data binding overview&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the lip-sync requirement specific
&lt;/h2&gt;

&lt;p&gt;For a simple stylized character, audio-driven mouth opening may be a suitable starting point.&lt;/p&gt;

&lt;p&gt;An example specification could define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt; as a closed mouth.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0.5&lt;/code&gt; as a medium opening.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; as the maximum designed opening.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those values are an example contract, not a universal Rive API.&lt;/p&gt;

&lt;p&gt;Your implementation also needs to handle silence, smoothing, playback timing, and interruption.&lt;/p&gt;

&lt;p&gt;If you need distinct mouth shapes for speech sounds, discuss a viseme-based system. That requires an agreed shape mapping and suitable timing data from your speech pipeline or analysis layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A useful project brief describes the expected result, not just “add lip sync.”&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What should be checked before launch?
&lt;/h2&gt;

&lt;p&gt;Test the character inside the real interface.&lt;/p&gt;

&lt;p&gt;A few important checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The mouth closes during silence.&lt;/li&gt;
&lt;li&gt;[ ] Speaking starts with audio playback.&lt;/li&gt;
&lt;li&gt;[ ] Interrupting playback stops mouth movement.&lt;/li&gt;
&lt;li&gt;[ ] The listening state matches actual microphone availability.&lt;/li&gt;
&lt;li&gt;[ ] Rapid state changes do not leave the avatar stuck.&lt;/li&gt;
&lt;li&gt;[ ] Expressions remain readable on smaller screens.&lt;/li&gt;
&lt;li&gt;[ ] Status text remains available alongside visual reactions.&lt;/li&gt;
&lt;li&gt;[ ] Reduced-motion behaviour is defined.&lt;/li&gt;
&lt;li&gt;[ ] Performance is acceptable on target devices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agree on who handles each check and how integration feedback will be addressed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to request a custom Rive avatar quote
&lt;/h2&gt;

&lt;p&gt;The most useful starting point is a short product brief.&lt;/p&gt;

&lt;p&gt;Send:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Your app:&lt;/strong&gt; a link, screenshot, or short explanation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your stack:&lt;/strong&gt; React, another web framework, or a different platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your character:&lt;/strong&gt; existing artwork or visual references.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Required behaviours:&lt;/strong&gt; listening, thinking, speaking, rewards, or other reactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice setup:&lt;/strong&gt; how speech is generated and played, if already decided.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline and budget:&lt;/strong&gt; your target launch date and budget range.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The quote can then account for design complexity, rigging, animation states, lip-sync requirements, transitions, and handoff scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bring your AI avatar idea to Mascot Engine
&lt;/h2&gt;

&lt;p&gt;If you are looking to hire a Rive animator for an AI web app, &lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt; is my studio for custom interactive character animation.&lt;/p&gt;

&lt;p&gt;I work with founders, developers, and product teams that need a character designed and animated around their application.&lt;/p&gt;

&lt;p&gt;Whether you have finished mascot artwork or an early product concept, we can discuss the behaviours your avatar needs and define the animation scope.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Let’s give your AI a face.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🌐 &lt;strong&gt;Explore my work:&lt;/strong&gt; &lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;MascotEngine.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
📧 &lt;strong&gt;Email your brief:&lt;/strong&gt; &lt;a href="mailto:mascotengine@gmail.com"&gt;mascotengine@gmail.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💬 &lt;strong&gt;WhatsApp:&lt;/strong&gt; &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;+94 71 700 0999&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Send your app screenshot, platform, and required avatar states to discuss a project quote.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Developers: what are you building, and what would you want your AI avatar to do first?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aiavatar</category>
      <category>avatar</category>
      <category>riveavatar</category>
    </item>
    <item>
      <title>How to Build an AI Companion That Listens, Thinks, Speaks, and Reacts in Real Time</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Thu, 17 Sep 2026 18:57:44 +0000</pubDate>
      <link>https://dev.to/uianimation/how-to-build-an-ai-companion-that-listens-thinks-speaks-and-reacts-in-real-time-122l</link>
      <guid>https://dev.to/uianimation/how-to-build-an-ai-companion-that-listens-thinks-speaks-and-reacts-in-real-time-122l</guid>
      <description>&lt;p&gt;AI assistants are becoming more capable every year.&lt;/p&gt;

&lt;p&gt;They can understand speech, generate natural responses, remember context, analyze user intent, and communicate using realistic voices.&lt;/p&gt;

&lt;p&gt;But there is still one major problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most AI products have no visible personality.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A user speaks.&lt;/p&gt;

&lt;p&gt;The system processes the request.&lt;/p&gt;

&lt;p&gt;A voice answers.&lt;/p&gt;

&lt;p&gt;But visually, there may be nothing more than a waveform, glowing orb, loading spinner, or static avatar.&lt;/p&gt;

&lt;p&gt;For many products, that is a missed opportunity.&lt;/p&gt;

&lt;p&gt;A well-designed interactive mascot can become the visual personality layer between the AI system and the user.&lt;/p&gt;

&lt;p&gt;Instead of simply showing that an AI is “loading,” a character can visibly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;listen&lt;/li&gt;
&lt;li&gt;think&lt;/li&gt;
&lt;li&gt;speak&lt;/li&gt;
&lt;li&gt;react&lt;/li&gt;
&lt;li&gt;celebrate&lt;/li&gt;
&lt;li&gt;show empathy&lt;/li&gt;
&lt;li&gt;recover from errors&lt;/li&gt;
&lt;li&gt;fall asleep when inactive&lt;/li&gt;
&lt;li&gt;follow the user's cursor or touch position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article explains how I approach building these systems using &lt;strong&gt;Rive, State Machines, runtime inputs, lip sync, and AI application events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are building an AI assistant, AI tutor, voice companion, SaaS copilot, or conversational application, this architecture can be used to turn a static mascot into a real product interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Important Shift: Stop Thinking About Animation Clips
&lt;/h2&gt;

&lt;p&gt;The first mistake is treating an AI character as a collection of animations.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idle.riv
thinking.riv
talking.riv
happy.riv
error.riv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can work for simple projects, but it quickly becomes difficult to maintain.&lt;/p&gt;

&lt;p&gt;A better approach is to think of the mascot as a &lt;strong&gt;small visual system controlled by the application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The application already knows what the AI is doing.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User is speaking
AI is processing
AI is responding
Connection failed
Answer was correct
User has been inactive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The animation system should receive these events and visually represent them.&lt;/p&gt;

&lt;p&gt;This means the mascot becomes part of the application logic rather than an animation playing on top of the UI.&lt;/p&gt;

&lt;p&gt;This is also the approach we focus on at &lt;strong&gt;Mascot Engine&lt;/strong&gt;, where interactive Rive mascots are prepared around real product events, AI responses, runtime inputs, and developer handoff.&lt;/p&gt;

&lt;p&gt;Mascot Engine:&lt;br&gt;
&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;https://mascotengine.com&lt;/a&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  A Simple AI Companion Architecture
&lt;/h1&gt;

&lt;p&gt;A production-ready AI character does not necessarily need dozens of separate controls.&lt;/p&gt;

&lt;p&gt;You can build a surprisingly flexible system using a few well-planned inputs.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity
emotion
viseme
audioLevel
lookX
lookY
blink
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break these down.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Activity State
&lt;/h1&gt;

&lt;p&gt;The first input controls what the AI is currently doing.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity = 0  // Idle
activity = 1  // Listening
activity = 2  // Thinking
activity = 3  // Speaking
activity = 4  // Connecting
activity = 5  // Error
activity = 6  // Sleeping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the application can control the character using its actual internal state.&lt;/p&gt;

&lt;p&gt;Example flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User starts speaking
        ↓
activity = 1

User finishes speaking
        ↓
activity = 2

LLM begins generating the response
        ↓
activity = 3

Response finishes
        ↓
activity = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mascot is no longer guessing what should happen.&lt;/p&gt;

&lt;p&gt;It is simply visualizing the state of the application.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Emotion Should Be Independent
&lt;/h1&gt;

&lt;p&gt;Activity and emotion should usually be separated.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because an AI can be speaking while happy, concerned, empathetic, surprised, or neutral.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;emotion = 0  // Neutral
emotion = 1  // Happy
emotion = 2  // Empathetic
emotion = 3  // Concerned
emotion = 4  // Surprised
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can combine states.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity = speaking
emotion = happy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity = speaking
emotion = concerned
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This dramatically reduces the number of animations that need to be created.&lt;/p&gt;

&lt;p&gt;Instead of manually creating:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;happy-speaking
sad-speaking
concerned-speaking
surprised-speaking
happy-listening
concerned-listening
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the system can layer reusable behaviors.&lt;/p&gt;

&lt;p&gt;This modular approach is one reason State Machines work particularly well for interactive characters.&lt;/p&gt;

&lt;p&gt;Rive has also demonstrated this idea in real AI-character use cases. For Duolingo's AI-powered Video Call experience, modular animation and State Machine blending were used to help Lily listen, process, and react dynamically rather than relying on a huge library of pre-baked reactions.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Listening State
&lt;/h1&gt;

&lt;p&gt;Listening should communicate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I am paying attention to you.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not need to be dramatic.&lt;/p&gt;

&lt;p&gt;Subtle behaviors often work better.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;slightly leaning forward&lt;/li&gt;
&lt;li&gt;focusing the eyes&lt;/li&gt;
&lt;li&gt;reducing random idle movement&lt;/li&gt;
&lt;li&gt;occasional blinking&lt;/li&gt;
&lt;li&gt;subtle head movement&lt;/li&gt;
&lt;li&gt;reacting slightly to microphone activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important point is that the user should immediately understand that the system is receiving input.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Thinking State
&lt;/h1&gt;

&lt;p&gt;Thinking is one of the most important AI states because latency becomes much easier to tolerate when the interface acknowledges it.&lt;/p&gt;

&lt;p&gt;Instead of freezing the character, the mascot can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;look upward&lt;/li&gt;
&lt;li&gt;glance sideways&lt;/li&gt;
&lt;li&gt;move its eyes slowly&lt;/li&gt;
&lt;li&gt;change posture&lt;/li&gt;
&lt;li&gt;perform a subtle thinking loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to fake intelligence.&lt;/p&gt;

&lt;p&gt;The goal is to clearly communicate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Your request was received and the system is processing it.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  5. Speaking State
&lt;/h1&gt;

&lt;p&gt;Speaking should not simply mean playing a looping mouth animation.&lt;/p&gt;

&lt;p&gt;There are multiple levels of implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1 — Basic talking animation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;isTalking = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A mouth animation loops while speech is active.&lt;/p&gt;

&lt;p&gt;Simple and lightweight.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 2 — Audio-driven mouth movement
&lt;/h2&gt;

&lt;p&gt;The application sends something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;audioLevel = 0.0 → 1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mouth responds to audio amplitude.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.0 = closed
0.3 = slightly open
0.7 = open
1.0 = fully open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much more convincing than a random speaking loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 3 — Viseme Lip Sync
&lt;/h2&gt;

&lt;p&gt;For more advanced AI voice products, the application can provide phoneme or viseme information.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;viseme = 0
viseme = 1
viseme = 2
...
viseme = 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each value represents a mouth shape.&lt;/p&gt;

&lt;p&gt;The result can feel significantly more natural.&lt;/p&gt;

&lt;p&gt;Recent Rive character examples also demonstrate layered State Machine systems with visemes, expressions, triggers, and speech-driven lip sync inside a single interactive character file.&lt;/p&gt;

&lt;p&gt;At Mascot Engine, this is one of the systems we can prepare for AI and TTS-driven products:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;https://mascotengine.com&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Interactive Eye Tracking
&lt;/h1&gt;

&lt;p&gt;Another relatively small feature can make a huge difference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lookX = -1 → 1
lookY = -1 → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These values can be connected to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cursor position&lt;/li&gt;
&lt;li&gt;touch position&lt;/li&gt;
&lt;li&gt;camera direction&lt;/li&gt;
&lt;li&gt;product UI events&lt;/li&gt;
&lt;li&gt;predefined conversational behaviors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lookX = -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Character looks left.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lookX = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Character looks right.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lookX = 0
lookY = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Character returns to the center.&lt;/p&gt;

&lt;p&gt;A subtle gaze system can make the character feel much more aware of the interface around it.&lt;/p&gt;

&lt;p&gt;Mascot Engine uses similar runtime-ready controls for interactive gaze, AI states, product reactions, and other app-driven behaviors.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Success, Failure, and Product Events
&lt;/h1&gt;

&lt;p&gt;Do not make the mascot respond only to the AI conversation.&lt;/p&gt;

&lt;p&gt;It can also respond to product events.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;answerCorrect
answerIncorrect
goalCompleted
paymentSuccessful
streakReached
levelUp
connectionLost
retry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI education apps&lt;/li&gt;
&lt;li&gt;habit trackers&lt;/li&gt;
&lt;li&gt;health applications&lt;/li&gt;
&lt;li&gt;fintech products&lt;/li&gt;
&lt;li&gt;productivity apps&lt;/li&gt;
&lt;li&gt;onboarding experiences&lt;/li&gt;
&lt;li&gt;gamified SaaS products&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine an AI learning app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Student answers correctly
       ↓
success trigger
       ↓
Mascot celebrates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The character is now reinforcing the product experience.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. What About Inactivity?
&lt;/h1&gt;

&lt;p&gt;AI companions can also respond when nothing is happening.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0–5 minutes
Idle

5–10 minutes
Bored / relaxed

10+ minutes
Sleeping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wake trigger
      ↓
wake animation
      ↓
idle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These small details make a character feel much more persistent.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Build One State Machine, Not 30 Disconnected Animations
&lt;/h1&gt;

&lt;p&gt;A simplified architecture might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌─────────────┐
                 │    IDLE     │
                 └──────┬──────┘
                        │
         ┌──────────────┼──────────────┐
         ↓              ↓              ↓
     LISTENING       THINKING        ERROR
         │              │
         └──────────┬───┘
                    ↓
                 SPEAKING
                    │
                    ↓
                   IDLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then emotion, blinking, gaze, and mouth behavior can operate as additional layers.&lt;/p&gt;

&lt;p&gt;This creates a much cleaner system than manually triggering unrelated clips.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Example Runtime Contract
&lt;/h1&gt;

&lt;p&gt;Before handing the animation to developers, I like to define a simple contract.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artboard:
AI_Companion

State Machine:
CompanionController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity
Number
0–6

emotion
Number
0–4

viseme
Number
0–9

audioLevel
Number
0–1

lookX
Number
-1–1

lookY
Number
-1–1

blink
Trigger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then document exactly what every input means.&lt;/p&gt;

&lt;p&gt;This sounds simple, but it prevents a huge number of integration problems.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. Example AI Event Mapping
&lt;/h1&gt;

&lt;p&gt;The development team can then map existing application events to the character.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;onUserSpeechStarted&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;onUserSpeechEnded&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;onAIResponseStarted&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;onAIResponseFinished&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;onConnectionError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact implementation depends on your framework and AI architecture.&lt;/p&gt;

&lt;p&gt;But the animation contract stays predictable.&lt;/p&gt;

&lt;p&gt;That is the important part.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. Where the AI Fits
&lt;/h1&gt;

&lt;p&gt;The mascot itself does not need to contain the AI.&lt;/p&gt;

&lt;p&gt;Think of it as three separate layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI / LLM
     ↓
Application Logic
     ↓
Rive Character
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM decides what to say.&lt;/p&gt;

&lt;p&gt;Your application manages the conversation.&lt;/p&gt;

&lt;p&gt;Rive visualizes what is happening.&lt;/p&gt;

&lt;p&gt;This separation makes the system easier to maintain.&lt;/p&gt;




&lt;h1&gt;
  
  
  13. What About AI-Generated Emotion?
&lt;/h1&gt;

&lt;p&gt;You can take this one step further.&lt;/p&gt;

&lt;p&gt;Suppose the AI returns structured metadata alongside its response.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You did really well today."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"emotion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"happy"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application maps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;happy → emotion = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the mascot speaks using the correct facial expression.&lt;/p&gt;

&lt;p&gt;You could use the same idea for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;neutral
happy
empathetic
concerned
surprised
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important rule is to keep the animation interface simple.&lt;/p&gt;

&lt;p&gt;Do not expose dozens of animation controls to the LLM if five stable states will achieve the same result.&lt;/p&gt;




&lt;h1&gt;
  
  
  14. Where This Architecture Works Well
&lt;/h1&gt;

&lt;p&gt;I especially like this approach for:&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Tutors
&lt;/h2&gt;

&lt;p&gt;The character can listen, think, explain answers, celebrate correct responses, and react to mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Companions
&lt;/h2&gt;

&lt;p&gt;A persistent character can visually communicate emotion and conversation state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Voice Assistants
&lt;/h2&gt;

&lt;p&gt;Listening, processing, speaking, interruption, and connection states become visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  SaaS Copilots
&lt;/h2&gt;

&lt;p&gt;A mascot can guide onboarding and respond to product events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kids' AI Products
&lt;/h2&gt;

&lt;p&gt;Visual communication can make abstract system states easier to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Health and Wellness Apps
&lt;/h2&gt;

&lt;p&gt;A calm companion can communicate support and progress without overwhelming the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Productivity Apps
&lt;/h2&gt;

&lt;p&gt;The mascot can react to goals, focus sessions, completion, streaks, and inactivity.&lt;/p&gt;




&lt;h1&gt;
  
  
  15. Why Rive Works Well for This
&lt;/h1&gt;

&lt;p&gt;There are several reasons I use Rive for these projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runtime control
&lt;/h3&gt;

&lt;p&gt;The application can control inputs while the character is running.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Machines
&lt;/h3&gt;

&lt;p&gt;Complex transitions can be kept inside the animation system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reusable rigs
&lt;/h3&gt;

&lt;p&gt;The same character foundation can support many behaviors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interactive animation
&lt;/h3&gt;

&lt;p&gt;The mascot can react to product data rather than simply playing videos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web and app workflows
&lt;/h3&gt;

&lt;p&gt;The same animation concept can be prepared for modern product environments.&lt;/p&gt;

&lt;p&gt;Rive's own marketplace increasingly includes production-oriented mascot examples built around State Machines, expressions, interactive controls, cursor tracking, data binding, and AI-like listening/thinking states.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. The Developer Handoff Matters as Much as the Animation
&lt;/h1&gt;

&lt;p&gt;A beautiful character that developers cannot integrate easily is not production-ready.&lt;/p&gt;

&lt;p&gt;A good delivery should clearly define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.riv source
artboard names
State Machine names
input names
input types
number ranges
event mappings
default values
fallback behavior
responsive behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the project, it can also include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PNG stills
editable source
Flutter guidance
React Native guidance
Web guidance
test implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At Mascot Engine, the focus is specifically on this kind of production-ready Rive mascot system rather than only delivering isolated animation loops.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. A Practical Minimum Viable AI Companion
&lt;/h1&gt;

&lt;p&gt;You do not need 50 animations for version one.&lt;/p&gt;

&lt;p&gt;A strong MVP could contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idle
Listening
Thinking
Speaking
Happy
Concerned
Error
Sleeping
Blink
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;plus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;audioLevel
lookX
lookY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is already enough to create a surprisingly expressive AI interface.&lt;/p&gt;

&lt;p&gt;You can always expand it later.&lt;/p&gt;




&lt;h1&gt;
  
  
  18. The Bigger Idea
&lt;/h1&gt;

&lt;p&gt;The interesting opportunity is not simply adding animation to AI.&lt;/p&gt;

&lt;p&gt;It is giving the AI system a consistent &lt;strong&gt;visual behavior layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The AI already has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;intelligence&lt;/li&gt;
&lt;li&gt;memory&lt;/li&gt;
&lt;li&gt;voice&lt;/li&gt;
&lt;li&gt;context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mascot provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;presence&lt;/li&gt;
&lt;li&gt;expression&lt;/li&gt;
&lt;li&gt;feedback&lt;/li&gt;
&lt;li&gt;personality&lt;/li&gt;
&lt;li&gt;visual state communication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I believe interactive characters will become increasingly useful inside AI products.&lt;/p&gt;

&lt;p&gt;The goal is not to put a cartoon character everywhere.&lt;/p&gt;

&lt;p&gt;The goal is to use a character where human-like visual feedback improves the product experience.&lt;/p&gt;




&lt;h1&gt;
  
  
  Need an AI Companion or Interactive Rive Mascot?
&lt;/h1&gt;

&lt;p&gt;I run &lt;strong&gt;Mascot Engine&lt;/strong&gt;, a studio focused on production-ready interactive Rive characters for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI assistants&lt;/li&gt;
&lt;li&gt;AI companions&lt;/li&gt;
&lt;li&gt;AI tutors&lt;/li&gt;
&lt;li&gt;SaaS products&lt;/li&gt;
&lt;li&gt;mobile apps&lt;/li&gt;
&lt;li&gt;web applications&lt;/li&gt;
&lt;li&gt;conversational interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Projects can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;character preparation&lt;/li&gt;
&lt;li&gt;Rive rigging&lt;/li&gt;
&lt;li&gt;idle / listening / thinking / speaking states&lt;/li&gt;
&lt;li&gt;interactive State Machines&lt;/li&gt;
&lt;li&gt;emotion systems&lt;/li&gt;
&lt;li&gt;eye tracking&lt;/li&gt;
&lt;li&gt;audio-driven mouth animation&lt;/li&gt;
&lt;li&gt;viseme lip sync&lt;/li&gt;
&lt;li&gt;product-event reactions&lt;/li&gt;
&lt;li&gt;editable Rive files&lt;/li&gt;
&lt;li&gt;developer handoff&lt;/li&gt;
&lt;li&gt;Flutter, React Native, and web preparation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see live interactive mascot examples and technical details here:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;https://mascotengine.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are building an AI product and already have a mascot, UI prototype, character sketch, or even only an idea, you can send the product brief and required behaviors to Mascot Engine to plan the animation architecture before development.&lt;/p&gt;




&lt;p&gt;Do not ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What animation should the mascot play?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“What does the application know right now, and how should the character visually communicate that state?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That small change turns a mascot from decoration into part of the product.&lt;/p&gt;




&lt;h1&gt;
  
  
  Rive #AI #Animation #WebDevelopment #AppDevelopment #GenerativeAI #ArtificialIntelligence #SaaS #Flutter #ReactNative #UX #UIUX #CharacterAnimation #AIAssistant #AICompanion
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>aicompanion</category>
      <category>app</category>
      <category>development</category>
    </item>
    <item>
      <title>How to Brief an Interactive App Mascot: A Founder’s Rive Checklist</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:34:48 +0000</pubDate>
      <link>https://dev.to/uianimation/how-to-brief-an-interactive-app-mascot-a-founders-rive-checklist-n5l</link>
      <guid>https://dev.to/uianimation/how-to-brief-an-interactive-app-mascot-a-founders-rive-checklist-n5l</guid>
      <description>&lt;p&gt;“We need a friendly mascot for our app” is a good starting point for a conversation. It is not yet a brief that an animator and developer can estimate reliably.&lt;/p&gt;

&lt;p&gt;Two characters can look equally simple in a screenshot and require very different systems. One might wave once during onboarding. Another might listen, think, speak, follow gaze targets, recover from an interrupted request, and run inside three different applications.&lt;/p&gt;

&lt;p&gt;The difference is behavior, data, and delivery scope. Describe those early and you give the project a much better chance of arriving in a form your team can use.&lt;/p&gt;

&lt;p&gt;This guide is for founders, product designers, and engineering leads commissioning an interactive Rive mascot or AI companion. It includes a copyable project brief and explains which decisions belong in it. The examples are fictional scoping examples, not claims about client work or fixed market prices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the product job
&lt;/h2&gt;

&lt;p&gt;Before choosing expressions or colors, describe what the character helps the user understand or do.&lt;/p&gt;

&lt;p&gt;An onboarding guide might explain progress and acknowledge completed steps. A support assistant might show whether it is listening or waiting for an answer. A learning companion might react to an exercise result without distracting from the lesson.&lt;/p&gt;

&lt;p&gt;Write one sentence that connects the character to a user task. For example: “The mascot helps users understand whether their voice request is being captured, processed, or answered.”&lt;/p&gt;

&lt;p&gt;Then name the screen or flow where that happens. A small companion beside a text field has different visual constraints from a full-screen character during a welcome sequence.&lt;/p&gt;

&lt;p&gt;Avoid making engagement or conversion promises part of the animation specification unless you have a plan to measure them. The deliverable can communicate a state clearly; the effect on broader product metrics needs evidence from your product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Describe one complete user journey
&lt;/h2&gt;

&lt;p&gt;A list of states is useful, but a sequence reveals the transitions and interruptions between them.&lt;/p&gt;

&lt;p&gt;Describe what happens from the user’s first action to the end of the interaction. Include one ordinary failure. For a voice assistant, the sequence might be: tap microphone, speak, wait, hear a response, interrupt, and retry after a network error.&lt;/p&gt;

&lt;p&gt;That journey answers questions a mood board cannot. Does speaking stop immediately? Does a success gesture block the next action? What remains visible while the service is unavailable?&lt;/p&gt;

&lt;p&gt;Keep the character’s role separate from the application’s role. Your app decides that a request succeeded. The character communicates the decision through animation.&lt;/p&gt;

&lt;p&gt;If the character can initiate an action when tapped, specify what that tap requests and which application component handles it. A visual interaction is not automatically a completed business operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  List states by meaning, not by personality
&lt;/h2&gt;

&lt;p&gt;Words like playful, calm, or confident help art direction. They do not define a State Machine.&lt;/p&gt;

&lt;p&gt;Give each state a product meaning and an exit condition. For example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;What ends it?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Idle&lt;/td&gt;
&lt;td&gt;Ready for interaction&lt;/td&gt;
&lt;td&gt;User begins a task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Listening&lt;/td&gt;
&lt;td&gt;Audio capture is active&lt;/td&gt;
&lt;td&gt;Capture stops or fails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thinking&lt;/td&gt;
&lt;td&gt;Waiting for the next result&lt;/td&gt;
&lt;td&gt;Answer, cancellation, or error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speaking&lt;/td&gt;
&lt;td&gt;Output audio is playing&lt;/td&gt;
&lt;td&gt;Playback ends or is interrupted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Success&lt;/td&gt;
&lt;td&gt;Requested operation completed&lt;/td&gt;
&lt;td&gt;Short acknowledgement finishes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unavailable&lt;/td&gt;
&lt;td&gt;Interaction cannot proceed&lt;/td&gt;
&lt;td&gt;Retry or return to a usable state&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are example states, not a requirement for every mascot. A simple onboarding character may need fewer. A complex companion may need additional behavior.&lt;/p&gt;

&lt;p&gt;Rive’s &lt;a href="https://rive.app/docs/editor/state-machine/state-machine" rel="noopener noreferrer"&gt;State Machine overview&lt;/a&gt; explains how animation states and transitions form an interactive system. Your brief should supply the product meaning that the designer maps into that system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate activity, expression, and attention
&lt;/h2&gt;

&lt;p&gt;You may want the character to speak warmly, wait calmly, and look toward a relevant interface element. Those behaviors do not all need to become separate primary states.&lt;/p&gt;

&lt;p&gt;Describe activity, emotion, and gaze as distinct concerns. This helps the specialist propose a manageable rig and control interface instead of multiplying every combination into another animation.&lt;/p&gt;

&lt;p&gt;Specify whether gaze follows a pointer, a tap target, or application events. It does not require a camera unless you explicitly want camera-based tracking and have planned that separate feature.&lt;/p&gt;

&lt;p&gt;Also describe the intensity of expression at the actual display size. A dramatic full-body reaction may work on a welcome screen but feel excessive beside a form field.&lt;/p&gt;

&lt;p&gt;Ask to review the character in a realistic product frame early. A beautiful standalone animation can still be the wrong size, contrast, or energy for its intended interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Say what artwork already exists
&lt;/h2&gt;

&lt;p&gt;Share the current source assets and explain what must remain recognizable: silhouette, proportions, palette, facial style, or accessories.&lt;/p&gt;

&lt;p&gt;Mention whether the artwork is editable vector art, a layered illustration, a flat image, or only a concept reference. These starting points require different preparation before rigging.&lt;/p&gt;

&lt;p&gt;If the character needs body turns, mouth poses, or expressions that are not visible in the original artwork, include that requirement. A single front-view image does not define every pose automatically.&lt;/p&gt;

&lt;p&gt;Clarify which references are for style and which are actual assets you are entitled to use. The brief should not leave the specialist guessing whether a reference character must be copied or merely communicates a general direction.&lt;/p&gt;

&lt;p&gt;Include ownership and editable-source delivery in the scope rather than waiting until the final export arrives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Name every target platform
&lt;/h2&gt;

&lt;p&gt;“Mobile and web” leaves important details unresolved. Specify Web, Flutter, React Native, or native platforms, and include the versions your developers already use when available.&lt;/p&gt;

&lt;p&gt;Rive provides runtimes for multiple environments, but feature support and renderer choices can differ. Its &lt;a href="https://rive.app/docs/runtimes/getting-started" rel="noopener noreferrer"&gt;runtime introduction&lt;/a&gt; is a useful reference for planning compatibility.&lt;/p&gt;

&lt;p&gt;List where the mascot appears and how many instances may be visible simultaneously. A single assistant panel and a scrolling collection of animated cards are different integration tasks.&lt;/p&gt;

&lt;p&gt;Mention offline requirements and asset delivery preferences. A bundled file, a remotely hosted file, and a remotely updated character system involve different release decisions.&lt;/p&gt;

&lt;p&gt;You do not need to know every technical answer before contacting a specialist. Mark unknowns honestly and identify the developer who can resolve them during scoping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native. View &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;live work and request an estimate&lt;/a&gt;, or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define speaking requirements before requesting lip sync
&lt;/h2&gt;

&lt;p&gt;“The character should talk” can mean several different deliverables.&lt;/p&gt;

&lt;p&gt;A repeating talking animation can signal activity. An audio-level-driven mouth can respond to loudness. Timed viseme animation selects mouth shapes associated with speech sounds. These options differ in appearance and in the data the application must provide.&lt;/p&gt;

&lt;p&gt;Say which speech system you use, whether audio is streamed, and whether timed mouth-shape or alignment data is available. Share a representative sample if you have one.&lt;/p&gt;

&lt;p&gt;Specify the languages and voice behaviors that matter to the product. Describe how interruptions, silence, buffering, and playback errors should affect the mouth.&lt;/p&gt;

&lt;p&gt;If you do not yet have timing data, ask the specialist to scope a fallback instead of assuming the &lt;code&gt;.riv&lt;/code&gt; file will derive accurate lip sync from arbitrary audio on its own.&lt;/p&gt;

&lt;p&gt;Keep speech generation, audio playback, timing data, and visual animation as separate responsibilities in the brief. That prevents an animation estimate from silently turning into an entire voice-platform implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask for a public control contract
&lt;/h2&gt;

&lt;p&gt;Your developer needs to know how application events drive the character.&lt;/p&gt;

&lt;p&gt;Rive’s Data Binding system connects View Model data to scene properties. The &lt;a href="https://rive.app/docs/editor/data-binding/overview" rel="noopener noreferrer"&gt;official overview&lt;/a&gt; explains the relationship between a schema, instances containing values, and bindings.&lt;/p&gt;

&lt;p&gt;You can describe the desired controls in plain language: current activity, expression, speech mouth shape, audio level, and gaze direction. The specialist can propose names and types.&lt;/p&gt;

&lt;p&gt;Ask for defaults, valid ranges, and ownership rules in the final documentation. A property called &lt;code&gt;progress&lt;/code&gt; should say whether it expects 0–1 or 0–100. An activity selector should enumerate every supported value.&lt;/p&gt;

&lt;p&gt;This contract is valuable even if your founder-facing brief remains nontechnical. It tells the engineering team what they will receive and gives the animator room to improve the design without exposing every internal object to code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specify what “developer-ready” includes
&lt;/h2&gt;

&lt;p&gt;Do you want an asset only, an integration example, or production implementation in your application? Name the boundary.&lt;/p&gt;

&lt;p&gt;For an asset handoff, request the runtime &lt;code&gt;.riv&lt;/code&gt;, editable project access or backup, entry-point names, control documentation, and runtime test notes. Rive distinguishes its &lt;a href="https://rive.app/docs/editor/exporting/exporting-for-runtime" rel="noopener noreferrer"&gt;runtime export&lt;/a&gt; from its &lt;a href="https://rive.app/docs/editor/exporting/exporting-for-backup" rel="noopener noreferrer"&gt;editable backup export&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For an integration example, define the platform and the interactions it must demonstrate. For production implementation, list the repository, screens, application events, audio responsibilities, and acceptance process.&lt;/p&gt;

&lt;p&gt;Avoid asking for a “complete handoff” without agreeing on its contents. Two people can use the phrase and imagine very different work.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dev.to/uianimation/rive-mascot-developer-handoff-a-production-checklist-for-web-and-mobile-22m8"&gt;Rive mascot developer handoff checklist&lt;/a&gt; provides a more detailed technical acceptance structure for your engineering team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Include accessibility and failure behavior
&lt;/h2&gt;

&lt;p&gt;A mascot should support the interface without becoming its only source of information.&lt;/p&gt;

&lt;p&gt;Describe the accompanying text and controls for important states such as listening, unavailable, or completed. If animation fails to load, users should still understand what they can do next.&lt;/p&gt;

&lt;p&gt;Ask for a reduced-motion treatment. That might be a quieter idle pose or static character with ordinary text feedback. React Native’s &lt;a href="https://reactnative.dev/docs/accessibilityinfo" rel="noopener noreferrer"&gt;AccessibilityInfo API&lt;/a&gt; is one example of a host mechanism for detecting motion preferences; the design still needs to specify the response.&lt;/p&gt;

&lt;p&gt;Review the character beside text at realistic sizes and on narrow screens. Include the intended background colors so contrast can be evaluated in context.&lt;/p&gt;

&lt;p&gt;Write at least one fallback acceptance criterion: “The user can complete onboarding if the character asset does not load.” It is simple, concrete, and easy to verify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explain the deadline and budget constraints
&lt;/h2&gt;

&lt;p&gt;A useful budget discussion starts with priorities, not an invented universal price for a mascot.&lt;/p&gt;

&lt;p&gt;Share a budget range and identify what is essential for the first release. New character design, complex rigging, multiple expressions, timed lip sync, platform testing, and production integration all affect the amount of work.&lt;/p&gt;

&lt;p&gt;Separate the launch date from the date your developers need the asset. Engineering integration and acceptance need time after visual approval.&lt;/p&gt;

&lt;p&gt;Name the decision-maker and the review process. If several people must approve artwork or behavior, make that visible before production begins.&lt;/p&gt;

&lt;p&gt;When budget or time is constrained, ask for a staged scope. A small reliable interaction set is easier to evaluate than a long list of unfinished behaviors. Keep later additions compatible with the initial control contract where practical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy this project brief
&lt;/h2&gt;

&lt;p&gt;Use this template as a starting point. Unknown answers are acceptable; unexplained assumptions are harder to manage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product and website:
Target users:
What the mascot helps users do:
Screens and approximate display size:

Existing artwork and editable source:
Visual references and must-keep features:
Required states and one complete user journey:
Interruption, error, and retry behavior:

Platforms and current framework/runtime versions:
Number of simultaneous character instances:
Offline or remote asset requirements:

Speaking required: yes/no
Speech provider and streaming behavior:
Available viseme/timing data:
Gaze behavior:
Reduced-motion and asset-failure fallback:

Deliverables: asset / demo / production integration
Editable source and ownership expectations:
Developer contact:
Acceptance tests and approval owner:

Budget range:
Asset handoff deadline:
Product launch date:
Essential first-release features:
Optional later features:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attach the relevant artwork and a short product walkthrough. A specialist should be able to understand the user journey without joining every internal planning conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review the proposal against the brief
&lt;/h2&gt;

&lt;p&gt;When a proposal arrives, compare the deliverables and exclusions against your requirements. Check that the speaking approach, runtime targets, editable-source access, and integration depth are stated explicitly.&lt;/p&gt;

&lt;p&gt;Ask how the result will be demonstrated before acceptance. A rendered video can approve appearance, but an interactive character also needs a runtime demonstration of its controls and transitions.&lt;/p&gt;

&lt;p&gt;Use the same brief when comparing options. Otherwise, one estimate may include source access and multi-platform testing while another covers only an animation export.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;Mascot Engine’s interactive character services&lt;/a&gt; cover Rive mascots, AI companions, rigging, State Machines, viseme lip sync, gaze controls, and developer-ready systems. A clear brief helps turn those capabilities into a scope that fits your actual product.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;View live work and request an estimate&lt;/a&gt;, or copy the brief above and &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send it on WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>startup</category>
      <category>design</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React Native Rive Migration: A Checklist for Production Mascots</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:32:31 +0000</pubDate>
      <link>https://dev.to/uianimation/react-native-rive-migration-a-checklist-for-production-mascots-4144</link>
      <guid>https://dev.to/uianimation/react-native-rive-migration-a-checklist-for-production-mascots-4144</guid>
      <description>&lt;p&gt;You update a Rive dependency, rebuild the React Native app, and the character still appears. Then the first conversation starts: a property is undefined, a ref is not ready, or a callback written for the previous API no longer behaves as expected.&lt;/p&gt;

&lt;p&gt;Visual continuity does not prove that an interactive mascot migration is complete. The important contract includes file loading, instance creation, public controls, error handling, and the lifecycle of the screen containing the character.&lt;/p&gt;

&lt;p&gt;The first decision is also easy to miss: are you moving from the legacy &lt;code&gt;rive-react-native&lt;/code&gt; package, or upgrading between versions of &lt;code&gt;@rive-app/react-native&lt;/code&gt;? Those are different migrations.&lt;/p&gt;

&lt;p&gt;This guide gives you a practical sequence for both situations. It is a planning and acceptance checklist, not a claim that an untested sample application works on every runtime version. Check the linked official documentation against the exact dependency versions you intend to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose a specific destination version
&lt;/h2&gt;

&lt;p&gt;Do not define the ticket as “upgrade to the latest Rive.” Define the package, version, supported native platforms, and the reason for moving.&lt;/p&gt;

&lt;p&gt;As checked on September 9, 2026, Rive’s &lt;a href="https://rive.app/docs/runtimes/react-native/migration-guide" rel="noopener noreferrer"&gt;React Native migration guide&lt;/a&gt; documents both the legacy-package migration and newer async API changes. It describes a &lt;code&gt;v0.5&lt;/code&gt; beta and recommends getting onto &lt;code&gt;v0.4.19&lt;/code&gt; or later with non-deprecated async APIs before trying that beta.&lt;/p&gt;

&lt;p&gt;Treat that as version-specific guidance, not a permanent promise about the release landscape. Recheck it when your migration starts.&lt;/p&gt;

&lt;p&gt;For a production app, separate the decision to update APIs from the decision to adopt a beta runtime. Smaller steps make it easier to identify regressions and restore a known working configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inventory the integration you actually have
&lt;/h2&gt;

&lt;p&gt;Search the application for package imports, Rive view components, file loaders, input setters, event listeners, text updates, and View Model access.&lt;/p&gt;

&lt;p&gt;Include code that only runs during errors, navigation, and speech interruption. Those paths often contain older calls that a successful first render will never exercise.&lt;/p&gt;

&lt;p&gt;Create a short inventory:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Record before changing anything&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dependencies&lt;/td&gt;
&lt;td&gt;React Native, Rive, and native support packages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build environment&lt;/td&gt;
&lt;td&gt;iOS/Android targets and relevant toolchain versions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assets&lt;/td&gt;
&lt;td&gt;File names, source locations, and external dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entry points&lt;/td&gt;
&lt;td&gt;Artboard, State Machine, View Model, and instance names&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Controls&lt;/td&gt;
&lt;td&gt;Types, ranges, defaults, and caller locations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifecycle&lt;/td&gt;
&lt;td&gt;Loading, subscriptions, disposal, and background behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;A reproducible interaction sequence on both native platforms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Save the original lockfile and exported asset with the migration branch. If your team uses remote assets, preserve the exact revision currently served rather than assuming the URL will always identify the same content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check native prerequisites before debugging the character
&lt;/h2&gt;

&lt;p&gt;Rive’s current &lt;a href="https://rive.app/docs/runtimes/react-native/react-native" rel="noopener noreferrer"&gt;React Native setup guide&lt;/a&gt; uses &lt;code&gt;@rive-app/react-native&lt;/code&gt; with Nitro Modules and lists the required React Native, Expo, native OS, and build-tool versions.&lt;/p&gt;

&lt;p&gt;Compare those requirements with the existing app before changing character behavior. A toolchain mismatch and a bad State Machine condition are not the same problem, even if both result in a character that does not work.&lt;/p&gt;

&lt;p&gt;Build a minimal screen that loads one known asset. Confirm the native integration on the platforms you support. Only then reconnect conversation state, microphone permissions, speech playback, and routing.&lt;/p&gt;

&lt;p&gt;If the app uses Expo, follow Rive’s setup requirements for that environment. Do not assume that an example working in a different native build arrangement proves compatibility with your project.&lt;/p&gt;

&lt;p&gt;Keep build logs from the failing stage. A precise error is more useful than repeatedly changing dependency versions without recording which combinations were attempted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make file loading an explicit state
&lt;/h2&gt;

&lt;p&gt;The character’s initial UI must handle pending, ready, and failed conditions. These are product states, not exceptional situations that can be ignored because the file usually loads quickly.&lt;/p&gt;

&lt;p&gt;Rive documents bundled and remote sources in &lt;a href="https://rive.app/docs/runtimes/react-native/loading-rive-files" rel="noopener noreferrer"&gt;Loading Rive Files&lt;/a&gt;. Choose the source according to your release and offline requirements.&lt;/p&gt;

&lt;p&gt;For a bundled asset, verify that the production build includes the file and that the bundler configuration supports it. For a remote asset, define retry behavior, unavailable-network behavior, and how you identify an asset revision.&lt;/p&gt;

&lt;p&gt;Keep a useful surrounding interface while loading. A support transcript, text input, or retry control should not depend on the animation being available.&lt;/p&gt;

&lt;p&gt;Avoid an indefinite spinner for every missing result. “Still loading,” “loaded but no matching View Model,” and “failed to load” need different handling if you want useful diagnostics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat file readiness and instance readiness separately
&lt;/h2&gt;

&lt;p&gt;Having a file object does not mean every interaction object is already available.&lt;/p&gt;

&lt;p&gt;The current migration guide describes asynchronous View Model instance creation and property-hook values that may initially be undefined. It also documents changes to loading and error return shapes across releases. Review the section corresponding to your starting version.&lt;/p&gt;

&lt;p&gt;Write the UI around explicit readiness conditions. Until the intended instance exists, preserve the latest desired character state in application data. Once ready, apply that snapshot.&lt;/p&gt;

&lt;p&gt;Do not fire every old event at the newly created instance. A sequence such as listening, thinking, speaking, then cancelled may have occurred while loading. The correct state now could simply be idle.&lt;/p&gt;

&lt;p&gt;This is especially important for AI companions. The conversation can advance independently of the visual asset, and the avatar needs to catch up to the current state rather than replay obsolete intent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Move product logic behind a small adapter
&lt;/h2&gt;

&lt;p&gt;A dependency upgrade is much harder when runtime-specific calls are spread throughout the app.&lt;/p&gt;

&lt;p&gt;Define a small interface in product terms. It might accept activity, expression, gaze, and speech controls. One adapter maps those values to the chosen Rive schema and runtime APIs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conversation or UI event
        |
        v
Current application state
        |
        v
Mascot adapter: validate and map
        |
        v
Ready Rive View Model instance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The names in the adapter should express intent. &lt;code&gt;setActivity("listening")&lt;/code&gt; is easier to reason about than a scattered numeric assignment whose meaning exists only in the editor file.&lt;/p&gt;

&lt;p&gt;Keep the mapping documented and versioned. If a property changes from a boolean to an enum or numeric selector, update the asset and adapter together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. Explore &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;live work&lt;/a&gt; and &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrate controls without changing their meaning
&lt;/h2&gt;

&lt;p&gt;Data Binding is the recommended direction for new Rive work. The official &lt;a href="https://rive.app/docs/editor/data-binding/migration-guide" rel="noopener noreferrer"&gt;Data Binding migration guide&lt;/a&gt; explains replacing legacy inputs and event-based communication with View Model properties.&lt;/p&gt;

&lt;p&gt;Preserve semantics during the move. An ongoing activity is different from a one-time request. A trigger asking the character to celebrate should not accidentally become a boolean that remains true forever.&lt;/p&gt;

&lt;p&gt;Document ranges and defaults. A zero value might mean idle, silence, a closed mouth, or the center of a coordinate system, depending on the property. The implementation needs the meaning, not just the type.&lt;/p&gt;

&lt;p&gt;For properties that represent discrete choices, reject or map unsupported values deliberately. For continuous values, decide whether clamping is appropriate. Handle missing data separately from a legitimate zero.&lt;/p&gt;

&lt;p&gt;If the migration also changes the artwork, keep a record of intentional visual differences. Otherwise, reviewers may not know whether a different pose is a redesign or a broken control mapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the async API consistently
&lt;/h2&gt;

&lt;p&gt;Mixing deprecated synchronous access with newer asynchronous access creates an integration that is difficult to reason about.&lt;/p&gt;

&lt;p&gt;Choose the documented API surface for your destination release and migrate callers systematically. Search again for old methods after the first implementation passes.&lt;/p&gt;

&lt;p&gt;Pay attention to the period between requesting an instance or property and receiving it. The owning screen may disappear, the file may change, or a newer operation may supersede the request.&lt;/p&gt;

&lt;p&gt;Associate asynchronous work with the owner and asset revision that requested it. If the result belongs to a stale owner, do not attach it to the current visible character.&lt;/p&gt;

&lt;p&gt;Avoid solving every readiness issue with a fixed timeout. Waiting an arbitrary number of milliseconds can hide a race on one device while leaving it on another. Use the runtime’s actual loading and readiness signals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coordinate navigation, backgrounding, and playback
&lt;/h2&gt;

&lt;p&gt;An interactive character lives inside an application lifecycle. It should not keep acting on a conversation that the product has already stopped.&lt;/p&gt;

&lt;p&gt;React Native’s &lt;a href="https://reactnative.dev/docs/appstate" rel="noopener noreferrer"&gt;AppState API&lt;/a&gt; reports foreground/background changes. Use those signals as inputs to your product policy; they do not by themselves decide whether speech should pause, stop, or continue.&lt;/p&gt;

&lt;p&gt;Write that policy explicitly. For example, leaving a voice-assistant screen might cancel playback and return the mouth to rest, while opening a small overlay might leave the conversation active.&lt;/p&gt;

&lt;p&gt;On resume, apply current state. Do not blindly replay an old speaking pose because the view was paused at that moment.&lt;/p&gt;

&lt;p&gt;Unsubscribe from application events when the owning component no longer needs them. Follow the runtime’s resource ownership rules so cached files remain valid for active consumers and abandoned instances do not keep receiving updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test interruption before polishing transitions
&lt;/h2&gt;

&lt;p&gt;The most convincing migration test is not a full animation playing from start to finish. It is a sequence that changes direction halfway through.&lt;/p&gt;

&lt;p&gt;Use a repeatable scenario on both iOS and Android:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the screen from a fresh app start.&lt;/li&gt;
&lt;li&gt;Start listening, then enter thinking.&lt;/li&gt;
&lt;li&gt;Begin speech and update gaze.&lt;/li&gt;
&lt;li&gt;Cancel speech before completion.&lt;/li&gt;
&lt;li&gt;Start a new interaction immediately.&lt;/li&gt;
&lt;li&gt;Deliver a late callback from the old interaction in your test harness.&lt;/li&gt;
&lt;li&gt;Confirm that the current session remains in control.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then test asset failure, missing properties, and navigating away during initialization. Each should produce a defined response rather than a frozen character or an indefinite loading state.&lt;/p&gt;

&lt;p&gt;If multiple characters appear at once, verify instance isolation. Updating one mascot should affect another only when the product intentionally shares state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep accessibility and fallback behavior intact
&lt;/h2&gt;

&lt;p&gt;A migration should preserve the useful non-animated interface as well as the visual feature.&lt;/p&gt;

&lt;p&gt;Keep status text, transcripts, retry actions, and playback controls accessible in the host app. If the character fails, the essential workflow should remain understandable.&lt;/p&gt;

&lt;p&gt;React Native’s &lt;a href="https://reactnative.dev/docs/accessibilityinfo" rel="noopener noreferrer"&gt;AccessibilityInfo API&lt;/a&gt; exposes reduced-motion preferences. Use those preferences according to the character’s designed reduced-motion behavior rather than treating them as a reason to remove necessary state feedback.&lt;/p&gt;

&lt;p&gt;Check text scaling and narrow layouts around the character. A successfully upgraded native module does not prove that the full product screen is still usable.&lt;/p&gt;

&lt;p&gt;Include these checks in acceptance so accessibility is not accidentally lost while developers focus on build errors and renamed methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define a rollback that restores a compatible pair
&lt;/h2&gt;

&lt;p&gt;A migration rollback should restore both the application integration and the asset version it expects.&lt;/p&gt;

&lt;p&gt;If you changed View Model names or control meanings, installing the previous package alone may not restore the previous behavior. Keep a known compatible combination of dependency lockfile, adapter, and &lt;code&gt;.riv&lt;/code&gt; asset.&lt;/p&gt;

&lt;p&gt;If you evaluate a beta runtime, record the reason and the acceptance results separately from the stable API migration. That makes the release decision concrete instead of relying on enthusiasm for a newer version.&lt;/p&gt;

&lt;p&gt;Do not silently update a remote production asset to a new schema while older app versions still use the previous one. Version your delivery path or preserve the contract expected by installed clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a finished migration should include
&lt;/h2&gt;

&lt;p&gt;The deliverable is a working, documented integration: destination versions, platform coverage, asset revision, control schema, lifecycle rules, known limitations, and a reproducible acceptance sequence.&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;Mascot Engine’s Rive integration and character services&lt;/a&gt;, a useful project brief includes the current package versions, target OS versions, exported asset, editable source availability, and the exact behavior that fails or needs to change.&lt;/p&gt;

&lt;p&gt;Mention whether you need migration support only or also want new rigging, expressions, lip sync, or State Machine work. Those are related tasks, but they should be estimated and verified separately.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;View live work and request an estimate&lt;/a&gt;, or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>reactnative</category>
      <category>mobile</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Rive Mascot Performance in Flutter: Loading, Caching and Lifecycle</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:29:37 +0000</pubDate>
      <link>https://dev.to/uianimation/rive-mascot-performance-in-flutter-loading-caching-and-lifecycle-4aib</link>
      <guid>https://dev.to/uianimation/rive-mascot-performance-in-flutter-loading-caching-and-lifecycle-4aib</guid>
      <description>&lt;p&gt;The mascot looks smooth on an empty Flutter screen. Then you put it beside a scrolling list, add speech playback, navigate away and back, and discover that the real product behaves differently.&lt;/p&gt;

&lt;p&gt;That does not automatically mean the character is too complex. The work may be happening in the wrong place: repeated loading, unnecessary widget rebuilds, controllers that outlive their screens, or multiple textures where a shared rendering arrangement would be appropriate.&lt;/p&gt;

&lt;p&gt;Performance work starts by identifying which cost you are paying. Download time, file parsing, state updates, rendering, and retained memory are different problems. A single “optimize the animation” ticket rarely captures them well.&lt;/p&gt;

&lt;p&gt;This guide proposes a practical workflow for Flutter teams shipping Rive mascots in onboarding, support, learning, or AI assistant interfaces. It does not present invented benchmark results or a universal fastest configuration. Use it to build and measure the integration your product actually needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the runtime generation you are using
&lt;/h2&gt;

&lt;p&gt;Rive’s Flutter APIs have evolved. Before comparing examples, record the Flutter version, &lt;code&gt;rive&lt;/code&gt; package version, renderer, target operating systems, and features used by the asset.&lt;/p&gt;

&lt;p&gt;The current &lt;a href="https://rive.app/docs/runtimes/flutter/flutter" rel="noopener noreferrer"&gt;Rive Flutter guide&lt;/a&gt; documents &lt;code&gt;RiveWidget&lt;/code&gt;, &lt;code&gt;RiveWidgetBuilder&lt;/code&gt;, file loaders, controllers, and shared rendering options. Its examples may differ from older tutorials using earlier APIs. Follow the guide for the version you adopt rather than combining unrelated generations of code.&lt;/p&gt;

&lt;p&gt;Keep that version record with the performance notes. Otherwise, a later developer may attribute a changed result to artwork when the runtime or renderer changed at the same time.&lt;/p&gt;

&lt;p&gt;Also list your lowest supported device tier. A smooth result on the newest phone is useful, but it is not an acceptance test for the rest of your audience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate the costs before changing the asset
&lt;/h2&gt;

&lt;p&gt;An interactive character can involve several independent stages:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Typical question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Retrieval&lt;/td&gt;
&lt;td&gt;Are bytes bundled locally or fetched remotely?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loading and parsing&lt;/td&gt;
&lt;td&gt;Is the same file initialized repeatedly?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instance setup&lt;/td&gt;
&lt;td&gt;Are controllers and View Models recreated unnecessarily?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application updates&lt;/td&gt;
&lt;td&gt;Does a small value change rebuild a large subtree?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rendering&lt;/td&gt;
&lt;td&gt;What is the cost of the visible scene and texture setup?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retention&lt;/td&gt;
&lt;td&gt;Which resources stay alive after leaving the screen?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Observe the symptom first. A slow first appearance points toward a different investigation than continuous frame drops. Memory that grows after repeated navigation suggests another category again.&lt;/p&gt;

&lt;p&gt;Use separate measurements for cold load and warm reuse. A cache can improve a repeat visit while leaving the first visit unchanged. Report both rather than choosing the more flattering result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reuse file data at an intentional scope
&lt;/h2&gt;

&lt;p&gt;If several screens use the same character asset, decide whether they should share a loaded file or load it independently.&lt;/p&gt;

&lt;p&gt;The right scope depends on frequency and lifetime. A mascot present throughout the application may justify a longer-lived owner. A character used once in an optional flow may be better loaded only when that feature opens.&lt;/p&gt;

&lt;p&gt;The official &lt;a href="https://rive.app/docs/runtimes/flutter/flutter" rel="noopener noreferrer"&gt;Rive Flutter documentation&lt;/a&gt; includes file-loading and reuse examples. Use them to establish one explicit owner rather than letting every widget invent its own cache.&lt;/p&gt;

&lt;p&gt;Ask four questions about that owner: who creates the resource, who may borrow it, when it can be released, and what invalidates it after an asset update?&lt;/p&gt;

&lt;p&gt;Avoid turning every asset into a permanent global. Reuse trades repeated work for retained resources. That trade can be sensible, but it still needs a reason.&lt;/p&gt;

&lt;p&gt;For remotely delivered files, distinguish in-memory reuse from a durable offline cache. Keeping an object alive during one session does not mean the file will remain available after a process restart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Share the file without accidentally sharing personality
&lt;/h2&gt;

&lt;p&gt;Two character widgets can use the same artwork while representing different interactions.&lt;/p&gt;

&lt;p&gt;Imagine a support mascot speaking in a panel while a smaller onboarding mascot waits in a card. If they share the same mutable control instance unintentionally, one screen’s activity updates may animate both.&lt;/p&gt;

&lt;p&gt;Rive’s &lt;a href="https://rive.app/docs/runtimes/flutter/data-binding" rel="noopener noreferrer"&gt;Flutter Data Binding guide&lt;/a&gt; distinguishes View Models from instances that contain values. Use that distinction to define which state is shared and which belongs to a particular visible character.&lt;/p&gt;

&lt;p&gt;Write down the ownership boundary in plain language: “The file is shared for reuse; each visible assistant has its own conversation state.” If synchronized characters are intentional, document that instead.&lt;/p&gt;

&lt;p&gt;This is a correctness issue as much as a performance issue. Reusing the wrong thing can make an efficient implementation behave incorrectly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep setup work out of frequently repeated builds
&lt;/h2&gt;

&lt;p&gt;Flutter can call &lt;code&gt;build()&lt;/code&gt; frequently. Its &lt;a href="https://docs.flutter.dev/perf/best-practices" rel="noopener noreferrer"&gt;performance best practices&lt;/a&gt; recommend avoiding expensive repeated work there and localizing state updates so unrelated descendants do not rebuild unnecessarily.&lt;/p&gt;

&lt;p&gt;Apply that principle to the mascot’s lifecycle. File loading, controller creation, and subscriptions should have deliberate owners and initialization points. A parent rebuilding should not silently create a new character session.&lt;/p&gt;

&lt;p&gt;For audio-driven motion, avoid using every audio sample as a reason to rebuild the whole page. Decide how values reach the already-ready character instance and update only the UI that actually needs a Flutter rebuild.&lt;/p&gt;

&lt;p&gt;Do not add layers of state management solely because an animation exists. A small, stable adapter is often easier to inspect than a large abstraction that hides when objects are created and disposed.&lt;/p&gt;

&lt;p&gt;Keep the product’s state independently accessible. If the character reloads, you should be able to apply the current snapshot without reconstructing the conversation from animation history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design the asynchronous exit path
&lt;/h2&gt;

&lt;p&gt;A user can leave a screen before its asset finishes loading. That path deserves the same attention as successful initialization.&lt;/p&gt;

&lt;p&gt;Plan what happens when loading completes after the owner is gone. The result may need to be released rather than attached to an obsolete widget. Avoid callbacks that update UI or character state after their subscription or owner has been disposed.&lt;/p&gt;

&lt;p&gt;The exact cleanup calls depend on whether you use a builder-managed integration or manually manage files and controllers. Follow the relevant API’s ownership rules and do not assume every object is disposed by the same component.&lt;/p&gt;

&lt;p&gt;For manual ownership, document the order in which subscriptions stop and resources are released. A shared file should remain alive while active consumers still need it.&lt;/p&gt;

&lt;p&gt;Test rapid navigation repeatedly. Open the screen, leave before loading completes, return, and begin an interaction. This sequence often reveals bugs that a single successful load does not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. Explore &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;live work at Mascot Engine&lt;/a&gt; and &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat shared rendering as a separate decision
&lt;/h2&gt;

&lt;p&gt;File reuse and rendering reuse are not the same optimization.&lt;/p&gt;

&lt;p&gt;Rive documents &lt;code&gt;RivePanel&lt;/code&gt; for drawing multiple widgets to a shared texture with the Rive Renderer. The current guide also describes manually managed shared textures for layouts that do not fit a common panel ancestor. These are rendering arrangements, not replacements for a clear file and controller lifecycle.&lt;/p&gt;

&lt;p&gt;Consider this option when multiple Rive graphics are visible together. First inspect whether their placement and stacking requirements fit the arrangement. Then compare it against your existing screen using the same device and interaction sequence.&lt;/p&gt;

&lt;p&gt;Do not promise that shared rendering makes every product faster. A screen with one small character is different from a list containing many graphics. The cost of the surrounding Flutter interface also remains relevant.&lt;/p&gt;

&lt;p&gt;If you adopt shared textures, include draw order, ownership, and release behavior in the integration notes. Otherwise, a future overlay or route change can invalidate assumptions that were never written down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let inactive characters become inactive
&lt;/h2&gt;

&lt;p&gt;A character does not need to perform the same amount of visual work in every product situation.&lt;/p&gt;

&lt;p&gt;Decide what happens when it is off-screen, behind another route, or in an inactive application. The appropriate policy might pause decorative motion, switch to a quiet pose, or stop a speech interaction. The choice depends on the feature’s behavior, not just the animation.&lt;/p&gt;

&lt;p&gt;Keep audio and visual state coordinated. Pausing the character while audio continues can be incorrect for a visible assistant; stopping audio merely because a decorative widget is rebuilt can be equally wrong.&lt;/p&gt;

&lt;p&gt;On resume, synchronize with the current application state. Do not automatically replay a previous speaking pose if playback has already ended.&lt;/p&gt;

&lt;p&gt;Include reduced-motion behavior in this policy. A static or restrained character can still communicate state through accompanying text and controls. Accessibility should be part of the design, not a last-minute performance fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a reproducible profiling session
&lt;/h2&gt;

&lt;p&gt;Flutter’s &lt;a href="https://docs.flutter.dev/tools/devtools/performance" rel="noopener noreferrer"&gt;DevTools Performance view&lt;/a&gt; is the starting point for investigating frame behavior. Follow its guidance for meaningful performance measurements rather than judging the final experience from debug-mode behavior alone.&lt;/p&gt;

&lt;p&gt;Create a short scenario that represents the product:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start from the chosen cold or warm condition.&lt;/li&gt;
&lt;li&gt;Open the screen and wait for the character to become ready.&lt;/li&gt;
&lt;li&gt;Scroll the surrounding content.&lt;/li&gt;
&lt;li&gt;Start the character’s most demanding interaction.&lt;/li&gt;
&lt;li&gt;Interrupt it and trigger a recoverable error.&lt;/li&gt;
&lt;li&gt;Leave the screen and return.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Record the device, build mode, runtime version, renderer, asset revision, and scenario duration. Keep these constant when comparing two implementations.&lt;/p&gt;

&lt;p&gt;Capture both an otherwise equivalent screen without the character and the complete screen with it. That comparison helps distinguish existing application costs from costs introduced by the integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure memory over repeated navigation
&lt;/h2&gt;

&lt;p&gt;An individual memory reading tells you little about lifecycle quality. Look at what happens after the same interaction is repeated.&lt;/p&gt;

&lt;p&gt;Open and close the feature several times under controlled conditions. Watch whether resources settle into the expected retained set or whether repeated visits keep increasing the baseline.&lt;/p&gt;

&lt;p&gt;Flutter provides a &lt;a href="https://docs.flutter.dev/tools/devtools/memory" rel="noopener noreferrer"&gt;DevTools Memory view&lt;/a&gt; for investigating memory behavior. Interpret its measurements alongside your ownership model; some retained resources may be intentional caches, while others may be abandoned subscriptions or instances.&lt;/p&gt;

&lt;p&gt;Do not call every retained object a leak. The useful question is whether the object still has a documented owner and purpose after the user leaves the feature.&lt;/p&gt;

&lt;p&gt;If the problem appears only after speech or a particular state, include that action in the reproduction sequence. A clean idle navigation test does not cover every resource the feature uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize the design after locating the bottleneck
&lt;/h2&gt;

&lt;p&gt;Once the profile points toward rendering or scene complexity, collaborate with the character designer.&lt;/p&gt;

&lt;p&gt;Review the work actually visible at the intended display size. Fine detail that is never perceived may not justify its cost. Inspect unnecessary animated properties and decorative movement that continues when it adds little value.&lt;/p&gt;

&lt;p&gt;Change one category at a time and compare the same scenario. Avoid simultaneously switching renderer, rewriting lifecycle code, and simplifying artwork; the result will not tell you which change mattered.&lt;/p&gt;

&lt;p&gt;Preserve behavioral acceptance while optimizing. A faster character that misses cancellation or displays the wrong emotion is not an improvement for the user.&lt;/p&gt;

&lt;p&gt;For complicated facial systems, separate property conflicts from performance problems. A mouth that snaps because two animations overwrite it does not necessarily indicate slow rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to include in a performance handoff
&lt;/h2&gt;

&lt;p&gt;Deliver the asset revision, runtime versions, file ownership plan, instance-sharing rules, cleanup policy, and the profiling scenario. Include results only for environments actually measured.&lt;/p&gt;

&lt;p&gt;A useful report says what changed and which cost it targeted. For example: “We moved file ownership above the repeated screen widgets to avoid reinitializing the same asset on each visit.” The measured effect belongs beside that statement, with the test conditions.&lt;/p&gt;

&lt;p&gt;Keep known limitations visible. If the character was tested on Android and iOS but not Flutter web, say so instead of treating Flutter as one identical execution environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;Mascot Engine’s interactive character services&lt;/a&gt; cover runtime-ready Rive assets and developer handoff. For an integration review, send the asset, Flutter and Rive versions, renderer, target devices, reproduction steps, and any existing profiles.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;View live work and request an estimate&lt;/a&gt;, or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>flutter</category>
      <category>performance</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Fixing Rive State Machine Conflicts: Blinking, Speaking and Gaze</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:26:24 +0000</pubDate>
      <link>https://dev.to/uianimation/fixing-rive-state-machine-conflicts-blinking-speaking-and-gaze-47je</link>
      <guid>https://dev.to/uianimation/fixing-rive-state-machine-conflicts-blinking-speaking-and-gaze-47je</guid>
      <description>&lt;p&gt;The mascot blinks correctly on its own. The speaking animation also works. Put them together, and the eyes freeze, the mouth snaps, or the head stops following the pointer.&lt;/p&gt;

&lt;p&gt;It is tempting to add another condition until the preview looks right. That can hide the symptom while making the State Machine harder to understand.&lt;/p&gt;

&lt;p&gt;A more useful first question is: &lt;strong&gt;which systems are trying to control the same property at the same time?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This guide walks through a practical debugging method for interactive Rive characters. It separates three common sources of trouble: animation ownership, transition behavior, and competing application updates. The examples are illustrative; they are not claims about a named client project or a benchmark of a particular file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand what layers actually separate
&lt;/h2&gt;

&lt;p&gt;A State Machine layer can play one state at a time, and multiple layers allow concurrent animation or interaction. They do not automatically isolate the properties each animation touches.&lt;/p&gt;

&lt;p&gt;If two layers animate the same property, order affects the result. Rive’s current &lt;a href="https://rive.app/docs/editor/state-machine/layers" rel="noopener noreferrer"&gt;layer documentation&lt;/a&gt; describes lower layers in the list taking priority over layers above them when their animated properties overlap.&lt;/p&gt;

&lt;p&gt;That means a layer called &lt;code&gt;Blink&lt;/code&gt; is not guaranteed to control only blinking. If its animation also contains a head rotation keyframe, it can interfere with gaze or body motion.&lt;/p&gt;

&lt;p&gt;Layer names communicate intent. The animated properties determine the actual interaction. Debug the properties, not just the names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Reduce the failure to a short sequence
&lt;/h2&gt;

&lt;p&gt;Do not begin by changing several layers and transition durations at once. First, write down the smallest sequence that reliably causes the problem.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Load the character in idle.
2. Set gaze to the upper-right target.
3. Begin speaking.
4. Trigger a blink.
5. Observe that gaze returns to center.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Record the expected and actual behavior separately. “Gaze breaks” is less useful than “the pupil position resets when Blink enters its closed-eye pose.”&lt;/p&gt;

&lt;p&gt;Repeat the sequence in the editor and in the target runtime. If it fails in both, inspect the asset first. If it fails only in the application, investigate initialization, control updates, and lifecycle behavior before rebuilding the rig.&lt;/p&gt;

&lt;p&gt;Save a copy or revision before editing. You want to compare one deliberate change against a stable baseline, not rely on memory after ten experiments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Build a property ownership table
&lt;/h2&gt;

&lt;p&gt;List the visible systems and the properties they should own. Keep the table small enough to use while inspecting the file.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Intended responsibility&lt;/th&gt;
&lt;th&gt;Possible conflict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Body activity&lt;/td&gt;
&lt;td&gt;Torso and broad posture&lt;/td&gt;
&lt;td&gt;Accidental head or facial keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gaze&lt;/td&gt;
&lt;td&gt;Eye target and permitted head adjustment&lt;/td&gt;
&lt;td&gt;Blink timeline resets the target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blink&lt;/td&gt;
&lt;td&gt;Eyelid closure&lt;/td&gt;
&lt;td&gt;Expression layer forces eyes open&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech&lt;/td&gt;
&lt;td&gt;Mouth pose or jaw opening&lt;/td&gt;
&lt;td&gt;Smile animation controls the same deformation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Emotion&lt;/td&gt;
&lt;td&gt;Brows, cheeks, restrained expression&lt;/td&gt;
&lt;td&gt;A full-face pose overwrites speech&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is an example architecture, not a mandatory Rive layout. Some characters need a different division. The goal is to make overlap intentional.&lt;/p&gt;

&lt;p&gt;Inspect each relevant timeline for keys outside its assigned area. A neutral pose keyed across the whole character can be convenient during authoring but surprising when mixed with other behaviors.&lt;/p&gt;

&lt;p&gt;Do not delete keys merely because they overlap. Decide whether they are necessary, whether they belong in another animation, or whether the combination needs an explicit design rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Isolate layers without losing their configuration
&lt;/h2&gt;

&lt;p&gt;Disable one suspected layer and replay the same sequence. Rive’s layer menu supports disabling a layer, which lets you isolate behavior without deleting the setup.&lt;/p&gt;

&lt;p&gt;If the problem disappears when the expression layer is disabled, you have narrowed the search. Re-enable it and inspect the properties that overlap with the failing system.&lt;/p&gt;

&lt;p&gt;Change one thing, replay, and record the result. This sounds slower than trying several fixes together, but it keeps you from accepting an accidental improvement that creates another bug elsewhere.&lt;/p&gt;

&lt;p&gt;Use priority as an explicit design choice. Reordering layers can be appropriate when one behavior really should dominate another. It is less convincing when the explanation is simply “this order looks okay in the current preview.”&lt;/p&gt;

&lt;p&gt;Once you have a proposed fix, test all the combinations that share those properties, not just the original failing sequence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Distinguish an ownership conflict from a transition delay
&lt;/h2&gt;

&lt;p&gt;Sometimes the intended state is selected, but the character appears unresponsive because the transition cannot leave when you expect.&lt;/p&gt;

&lt;p&gt;Rive transitions include conditions, duration, and optional exit behavior. Its &lt;a href="https://rive.app/docs/editor/state-machine/transitions" rel="noopener noreferrer"&gt;transition documentation&lt;/a&gt; explains Exit Time and Allow Exit During Transition. These settings affect whether a new request can take effect promptly.&lt;/p&gt;

&lt;p&gt;For an interruptible assistant, a cancellation path should not wait for an unrelated flourish to finish. For a decorative celebration, waiting for a gesture to complete may be exactly what you want.&lt;/p&gt;

&lt;p&gt;Write the behavior in product terms first: “Stop speaking as soon as playback stops” or “Finish the short acknowledgement unless a new conversation starts.” Then configure the transitions to match.&lt;/p&gt;

&lt;p&gt;Do not assume that a transition existing in one direction creates a return path. Verify entry and exit behavior independently, including paths that only run after an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Check conditions for ambiguity
&lt;/h2&gt;

&lt;p&gt;A character can look unpredictable when multiple conditions are true or when a transition has no meaningful guard.&lt;/p&gt;

&lt;p&gt;For example, three booleans named &lt;code&gt;listening&lt;/code&gt;, &lt;code&gt;thinking&lt;/code&gt;, and &lt;code&gt;speaking&lt;/code&gt; can describe impossible combinations if different callbacks update them independently. A single activity selector can reduce that ambiguity for a product that allows only one primary activity at a time.&lt;/p&gt;

&lt;p&gt;This does not mean every control should be merged. Gaze and emotion often need to remain independent of activity. The useful distinction is between mutually exclusive product modes and behaviors that should occur together.&lt;/p&gt;

&lt;p&gt;Document the valid combinations. If the app can listen while playing audio, that is a different requirement from a strictly turn-based assistant. The file should reflect the intended conversation model rather than accidentally choosing one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native. View &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;live character work&lt;/a&gt; or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send a project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Give the mouth one clear speaking strategy
&lt;/h2&gt;

&lt;p&gt;Speech is a frequent source of conflicts because several systems want to make the face expressive.&lt;/p&gt;

&lt;p&gt;A mouth can use an amplitude-driven opening value, a timed viseme selector, or a simple speaking loop. Each can be useful, but combining them requires a deliberate plan.&lt;/p&gt;

&lt;p&gt;Suppose a viseme selects closed lips while an audio-level blend forces the jaw open. Both systems are responding to valid data, but the resulting pose may be wrong. Decide whether amplitude is ignored in viseme mode or used only as a controlled secondary adjustment.&lt;/p&gt;

&lt;p&gt;Likewise, a smile animation should not unknowingly overwrite the exact mouth shape required for speech. You might place warmth in cheeks and brows, create compatible smiling mouth poses, or reduce the smile during particular visemes. That is a character design decision, not something runtime code can reliably guess.&lt;/p&gt;

&lt;p&gt;Test rest and silence as carefully as active speech. A cancelled utterance should not leave the last open mouth pose on screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Trace application writers
&lt;/h2&gt;

&lt;p&gt;If the asset behaves correctly in the editor, inspect the application’s update path.&lt;/p&gt;

&lt;p&gt;List every writer for each public property: conversation events, audio callbacks, idle timers, pointer handlers, route listeners, and setup code. One property can have several callers, but it should have a clear authority deciding its current value.&lt;/p&gt;

&lt;p&gt;For a difficult issue, log a compact record containing the property, new value, source, conversation ID, and time. Avoid logging private conversation content when the control data is enough to diagnose the animation.&lt;/p&gt;

&lt;p&gt;Consider this sequence: an utterance is cancelled, a new listening session starts, and the old utterance’s completion callback arrives late. If that callback unconditionally selects idle, it overrides the new session.&lt;/p&gt;

&lt;p&gt;Associate callbacks with the operation they belong to. Ignore stale events and derive the character state from the current application snapshot. No amount of layer reordering can fix an application that continually supplies the wrong activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Check initialization and instance identity
&lt;/h2&gt;

&lt;p&gt;Another common category is writing correct values to the wrong instance or at the wrong time.&lt;/p&gt;

&lt;p&gt;Rive separates a View Model definition from the instances containing actual values. The &lt;a href="https://rive.app/docs/runtimes/web/data-binding" rel="noopener noreferrer"&gt;Web Data Binding guide&lt;/a&gt; documents retrieving those instances after loading and binding them to the scene.&lt;/p&gt;

&lt;p&gt;Verify that the instance receiving updates is the one connected to the visible character. This matters when a screen contains multiple mascots or when navigation recreates a controller.&lt;/p&gt;

&lt;p&gt;If the application caches references to properties, replace those references when the underlying instance changes. A value written successfully to an old instance will not necessarily affect the new visible character.&lt;/p&gt;

&lt;p&gt;Also check initial values. An animation can appear to “snap back” because newly created state is applying defaults after your application already wrote its current snapshot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 9: Separate coordinate problems from animation conflicts
&lt;/h2&gt;

&lt;p&gt;Gaze bugs are not always State Machine bugs. A pointer position in screen coordinates is not automatically a useful value in the character’s local coordinate system.&lt;/p&gt;

&lt;p&gt;Write down the expected range and orientation for &lt;code&gt;lookX&lt;/code&gt; and &lt;code&gt;lookY&lt;/code&gt;. For example, both might use -1 to 1, with positive Y meaning down on screen. If the host uses the opposite convention, the character will look away from the target even when the rig is correct.&lt;/p&gt;

&lt;p&gt;Account for the character’s displayed bounds, fit, alignment, and any letterboxing. Recalculate the mapping when the layout changes. Clamp the final values and specify what happens when the target disappears.&lt;/p&gt;

&lt;p&gt;On a touch interface, choose an intentional attention target instead of waiting for mouse movement that never occurs. A neutral pose is usually better than stale gaze from a previous interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 10: Turn the fix into a regression checklist
&lt;/h2&gt;

&lt;p&gt;Once the original sequence passes, broaden the checks to nearby behaviors.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sequence&lt;/th&gt;
&lt;th&gt;What to verify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Idle plus blink&lt;/td&gt;
&lt;td&gt;No unintended head or mouth movement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speaking plus blink&lt;/td&gt;
&lt;td&gt;Speech continues while eyelids close&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speaking plus emotion&lt;/td&gt;
&lt;td&gt;Mouth poses remain readable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gaze plus layout resize&lt;/td&gt;
&lt;td&gt;Target mapping remains consistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancel plus new session&lt;/td&gt;
&lt;td&gt;Old callbacks do not overwrite activity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure plus retry&lt;/td&gt;
&lt;td&gt;The character exits the error state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screen leave and return&lt;/td&gt;
&lt;td&gt;Current application state is restored&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use the exported file in the actual target runtimes. Record package versions and renderer choices with the result. Rive’s &lt;a href="https://rive.app/docs/runtimes/getting-started" rel="noopener noreferrer"&gt;runtime introduction&lt;/a&gt; notes that support varies by feature and runtime, so editor-only verification is insufficient for a cross-platform release.&lt;/p&gt;

&lt;p&gt;You do not need a vast automated suite for every visual adjustment. You do need a repeatable way to reproduce the failure and show that the intended combinations still work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to include when requesting a repair
&lt;/h2&gt;

&lt;p&gt;A useful debugging brief contains the &lt;code&gt;.riv&lt;/code&gt; file, editable project access or backup, runtime version, target platform, current control schema, and a short reproduction sequence.&lt;/p&gt;

&lt;p&gt;Include a recording if it helps explain the symptom, but pair it with the values or events being sent. “The eyes freeze when activity changes from thinking to speaking” is much easier to investigate than “the mascot feels broken.”&lt;/p&gt;

&lt;p&gt;If several designers or developers have worked on the file, mention that history and identify the current source of truth. The first repair task may be reconstructing the intended contract.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;Mascot Engine’s Rive character services&lt;/a&gt; include rigging, State Machines, gaze controls, lip sync, and developer-ready handoff. Specialist help is useful when a local visual fix must remain compatible with speech, expression, and multiple runtimes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;View live work and request an estimate&lt;/a&gt;, or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>animation</category>
      <category>webdev</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Rive Data Binding vs State Machine Inputs: A Mascot Migration Guide</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:22:33 +0000</pubDate>
      <link>https://dev.to/uianimation/rive-data-binding-vs-state-machine-inputs-a-mascot-migration-guide-i55</link>
      <guid>https://dev.to/uianimation/rive-data-binding-vs-state-machine-inputs-a-mascot-migration-guide-i55</guid>
      <description>&lt;p&gt;Your mascot integration starts with three controls: wave, smile, and speaking. A few months later, the character also needs a progress value, a display name, theme colors, and a different reaction for each onboarding step.&lt;/p&gt;

&lt;p&gt;At that point, the problem is no longer how to trigger an animation. It is how to maintain a coherent interface between the application and the Rive file.&lt;/p&gt;

&lt;p&gt;Rive’s Data Binding system provides a broader interface than legacy State Machine Inputs. For an existing product, however, replacing an API call is only a small part of migration. You also need to preserve meaning, defaults, ownership, and the behavior users already rely on.&lt;/p&gt;

&lt;p&gt;This guide explains the architectural difference and proposes a migration workflow for interactive mascots. The examples are design sketches rather than a downloadable, tested &lt;code&gt;.riv&lt;/code&gt; integration. Match the API details to the runtime version in your project before implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes with Data Binding?
&lt;/h2&gt;

&lt;p&gt;Legacy State Machine Inputs expose numbers, booleans, and triggers used to control animation behavior. Data Binding exposes View Model properties with a wider set of types and lets those values connect to more than State Machine transitions.&lt;/p&gt;

&lt;p&gt;Rive recommends Data Binding for new work and future updates. Its current &lt;a href="https://rive.app/docs/editor/data-binding/migration-guide" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt; also says existing inputs and events continue to work; an already functioning production file does not require an emergency rewrite simply because a newer approach exists.&lt;/p&gt;

&lt;p&gt;That distinction helps with planning. You can keep a stable legacy integration running while defining the contract for its next release.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Legacy-input approach&lt;/th&gt;
&lt;th&gt;Data Binding approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What is the main public interface?&lt;/td&gt;
&lt;td&gt;Named inputs attached to State Machines&lt;/td&gt;
&lt;td&gt;Properties on View Model instances&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;How do you represent richer product data?&lt;/td&gt;
&lt;td&gt;Often with extra conventions and separate APIs&lt;/td&gt;
&lt;td&gt;With additional supported property types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What can data drive?&lt;/td&gt;
&lt;td&gt;Primarily animation state control&lt;/td&gt;
&lt;td&gt;Transitions and bound scene properties&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What should new work target?&lt;/td&gt;
&lt;td&gt;Compatibility needs may justify it&lt;/td&gt;
&lt;td&gt;Rive’s recommended direction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The benefit is not that every scene becomes simpler automatically. The benefit is having a more expressive place to define the contract. A poorly designed View Model can be just as confusing as a poorly named input list.&lt;/p&gt;

&lt;h2&gt;
  
  
  A View Model is a schema; an instance holds values
&lt;/h2&gt;

&lt;p&gt;Keep three concepts separate. A View Model defines the structure, a View Model instance holds values, and bindings connect those values to the scene. Rive’s &lt;a href="https://rive.app/docs/editor/data-binding/overview" rel="noopener noreferrer"&gt;Data Binding overview&lt;/a&gt; introduces these responsibilities.&lt;/p&gt;

&lt;p&gt;For a product mascot, the schema might describe activity, expression, progress, and gaze. One instance could be listening on an onboarding screen while another is idle in a support panel.&lt;/p&gt;

&lt;p&gt;Think carefully before sharing the mutable instance. Two characters may reuse the same exported file without being intended to mirror each other’s expression. Shared file data and shared interaction state solve different problems.&lt;/p&gt;

&lt;p&gt;Also distinguish a blank instance from the designer’s default instance. A blank numeric value of zero is not necessarily the intended neutral pose if the design uses a different convention. Record the intended initialization explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Begin with an inventory of actual behavior
&lt;/h2&gt;

&lt;p&gt;Before changing the editor file, list every place the app writes an input or listens for a response.&lt;/p&gt;

&lt;p&gt;Include startup code, error handlers, route changes, timers, speech callbacks, and any interaction originating inside the artboard. Integrations often look small until you include the paths that run after cancellation or navigation.&lt;/p&gt;

&lt;p&gt;For each existing control, record its name, type, meaning, default, writer, and observed effect. Then ask whether it represents persistent state or a momentary request.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;isSpeaking&lt;/code&gt; describes an ongoing condition. &lt;code&gt;celebrate&lt;/code&gt; asks for a one-time response. Converting both into booleans without an explicit reset rule changes their semantics.&lt;/p&gt;

&lt;p&gt;Capture a short set of reference interactions from the current product. You are establishing a behavioral baseline, not proving that every old implementation decision must survive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design the new contract before converting the file
&lt;/h2&gt;

&lt;p&gt;Suppose the legacy system exposes &lt;code&gt;isListening&lt;/code&gt;, &lt;code&gt;isThinking&lt;/code&gt;, and &lt;code&gt;isSpeaking&lt;/code&gt;. All three can accidentally become true. The file then has to resolve a combination that the product never intended.&lt;/p&gt;

&lt;p&gt;A single activity selector can make those states mutually exclusive at the application boundary. Keep expression separate so a warm speaking pose does not require a whole new activity value.&lt;/p&gt;

&lt;p&gt;Here is an example mapping:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Existing control&lt;/th&gt;
&lt;th&gt;Proposed property&lt;/th&gt;
&lt;th&gt;Migration decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Three activity booleans&lt;/td&gt;
&lt;td&gt;&lt;code&gt;activity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One documented selector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;smileAmount&lt;/code&gt; number&lt;/td&gt;
&lt;td&gt;&lt;code&gt;warmth&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Keep range 0–1 and define neutral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;celebrate&lt;/code&gt; trigger&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;celebrate&lt;/code&gt; trigger property&lt;/td&gt;
&lt;td&gt;Preserve momentary semantics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Direct text-run update&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;displayName&lt;/code&gt; string&lt;/td&gt;
&lt;td&gt;Bind the text in the file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Separate color mutations&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;accentColor&lt;/code&gt; color&lt;/td&gt;
&lt;td&gt;Bind intended visual elements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are example names, not official Rive conventions. The correct interface is the smallest one that expresses your product’s needs clearly.&lt;/p&gt;

&lt;p&gt;Avoid exposing every bone, transform, and timeline to application code. Public properties should describe meaningful controls. The designer needs room to improve the animation without changing every caller.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep an adapter between product events and Rive
&lt;/h2&gt;

&lt;p&gt;Do not scatter runtime-specific property access across your feature code. Put that access behind a small adapter that the rest of the application can call.&lt;/p&gt;

&lt;p&gt;The product might request &lt;code&gt;setActivity("listening")&lt;/code&gt;, while the adapter maps that to the file’s numeric or enum representation. If the schema changes later, the mapping has a clear owner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product event
    -&amp;gt; validate current conversation state
    -&amp;gt; map to the mascot contract
    -&amp;gt; update the bound View Model instance
    -&amp;gt; let the State Machine produce the visual response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation belongs at this boundary. Check allowed discrete values, clamp continuous values where appropriate, and reject non-finite numbers. Log meaningful integration errors in development rather than silently displaying the wrong state.&lt;/p&gt;

&lt;p&gt;Keep a current snapshot of persistent controls. If the asset finishes loading after the user has already entered listening mode, apply the snapshot rather than replaying every historical UI event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native. Explore &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;Mascot Engine’s live work&lt;/a&gt; and &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convert editor behavior and runtime code together
&lt;/h2&gt;

&lt;p&gt;Rive documents an editor command to convert inputs to View Models. Treat that as a migration aid, not a substitute for reviewing the resulting interface.&lt;/p&gt;

&lt;p&gt;Work on a versioned copy. Inspect each converted condition, blend, and interaction. Confirm that the properties intended for runtime control are available through the chosen instance and that the correct defaults are assigned.&lt;/p&gt;

&lt;p&gt;Then update the adapter to use the new properties. Avoid a halfway state where one callback writes a legacy input while another writes a View Model property controlling the same behavior.&lt;/p&gt;

&lt;p&gt;If you deliberately support both asset versions, make the selected contract explicit. Choose the adapter once when the asset is loaded. Guessing which interface exists during every update makes failures harder to reproduce.&lt;/p&gt;

&lt;p&gt;Keep the original exported file and matching application integration available for rollback. A rollback plan should restore a known pair, not mix an old asset with a new schema adapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web integration: readiness and binding come first
&lt;/h2&gt;

&lt;p&gt;The Web runtime exposes View Models and their instances after the file loads. It supports automatic binding to the default instance, as well as explicit binding. These details are documented in the &lt;a href="https://rive.app/docs/runtimes/web/data-binding" rel="noopener noreferrer"&gt;Web Data Binding guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A minimal property update can look like this inside a ready integration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Illustrative fragment: the Rive file must already be loaded,&lt;/span&gt;
&lt;span class="c1"&gt;// and the intended View Model instance must already be bound.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;riveInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;viewModelInstance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;progress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;progress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateProgress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;progress&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;progress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fragment intentionally does not load the file or manage the full lifecycle. In production, decide how a missing property should be reported and how references are replaced after an asset reload.&lt;/p&gt;

&lt;p&gt;Cache property references when the instance becomes ready. If you bind a new instance, obtain references from that new instance instead of continuing to write to the old one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flutter integration: be precise about ownership
&lt;/h2&gt;

&lt;p&gt;Flutter has its own controller and binding APIs; translating a JavaScript example word for word is not an integration strategy.&lt;/p&gt;

&lt;p&gt;Rive’s &lt;a href="https://rive.app/docs/runtimes/flutter/data-binding" rel="noopener noreferrer"&gt;Flutter Data Binding documentation&lt;/a&gt; describes creating instances, binding them through a controller, and retrieving typed properties. Use the documentation matching your installed runtime and follow the ownership rules of the objects you create.&lt;/p&gt;

&lt;p&gt;Place initialization at a stable lifecycle boundary. Recreating the file or controller whenever a parent widget rebuilds can hide migration bugs behind unrelated UI updates.&lt;/p&gt;

&lt;p&gt;Separate application state from the visual instance. When a screen returns, derive the character’s activity from the current product state. Do not assume that the last animation pose is the current source of truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Native integration: check which runtime you have
&lt;/h2&gt;

&lt;p&gt;There is an important package distinction between older examples and the current integration. Rive provides a &lt;a href="https://rive.app/docs/runtimes/react-native/migration-guide" rel="noopener noreferrer"&gt;React Native migration guide&lt;/a&gt; for moving to &lt;code&gt;@rive-app/react-native&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before copying any hook or ref method, verify its package and version. A correct example for one generation of the runtime can be wrong for another.&lt;/p&gt;

&lt;p&gt;Write down the native requirements and build configuration before making a broad migration. Confirm a minimal character integration first, then connect conversation events, audio, and navigation. This sequence makes it easier to distinguish a native setup problem from a View Model contract problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevent feedback loops in bidirectional designs
&lt;/h2&gt;

&lt;p&gt;When data can move in both directions, a scene interaction may update a property that the application is also observing. That can be useful, but the ownership rules must remain explicit.&lt;/p&gt;

&lt;p&gt;Consider a character that requests help when tapped. The request can flow into application logic. The app then decides whether to open a panel, start a session, or show an error.&lt;/p&gt;

&lt;p&gt;Do not immediately write a conflicting value back just because a listener fired. Record which updates represent user intent, which are application decisions, and which are visual completion signals.&lt;/p&gt;

&lt;p&gt;Keep important business operations outside animation callbacks. A success gesture can acknowledge a completed action; it should not be the only thing that makes the action happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test semantics, not just property access
&lt;/h2&gt;

&lt;p&gt;It is possible for every property lookup to succeed while the migration is still wrong.&lt;/p&gt;

&lt;p&gt;Use a test matrix that covers initial load, a normal interaction, interruption, failure, recovery, and two simultaneous character instances. Check that the correct character reacts and that a stale callback cannot overwrite newer state.&lt;/p&gt;

&lt;p&gt;Exercise boundary values deliberately. For progress, test zero, one, and an intermediate value. For activity, test each documented value and an invalid one. For a trigger, test two separate requests and establish what should happen if a second arrives before the first animation completes.&lt;/p&gt;

&lt;p&gt;Compare the migrated asset against the reference interactions you captured earlier. Document intentional differences so reviewers do not mistake a planned behavior change for a regression.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should be in the migration handoff?
&lt;/h2&gt;

&lt;p&gt;Deliver the updated editable project, runtime export, property schema, adapter mapping, defaults, lifecycle notes, and platform test results. Include a list of removed names so application developers can search for stale references.&lt;/p&gt;

&lt;p&gt;Version the schema as an integration artifact. Even a simple release note such as “activity is now a single selector; old activity booleans are removed” can prevent hours of confusion.&lt;/p&gt;

&lt;p&gt;For a broader view of the delivery package, use the &lt;a href="https://dev.to/uianimation/rive-mascot-developer-handoff-a-production-checklist-for-web-and-mobile-22m8"&gt;Rive mascot developer handoff checklist&lt;/a&gt; as a prompt to discuss integration requirements with your character specialist. The important outcome is a contract that both the designer and developer can explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a specialist is useful
&lt;/h2&gt;

&lt;p&gt;Bring in help when migration overlaps with rigging changes, lip sync, nested components, or multiple platforms. Changing the data interface while redesigning the character creates more variables than a simple API update.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt; builds interactive Rive character systems and provides &lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;rigging, State Machine, and developer handoff services&lt;/a&gt;. For a migration estimate, send the current runtime versions, existing control names, required platforms, and the behavior you need to preserve.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready systems for Web, Flutter, and React Native. &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;View live work and request an estimate&lt;/a&gt;, or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>webdev</category>
      <category>flutter</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Rive Mascot Developer Handoff: A Production Checklist for Web and Mobile</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:19:17 +0000</pubDate>
      <link>https://dev.to/uianimation/rive-mascot-developer-handoff-a-production-checklist-for-web-and-mobile-22m8</link>
      <guid>https://dev.to/uianimation/rive-mascot-developer-handoff-a-production-checklist-for-web-and-mobile-22m8</guid>
      <description>&lt;p&gt;A character waves beautifully in the preview. The designer sends a &lt;code&gt;.riv&lt;/code&gt; file. Your developer opens the integration ticket and immediately has questions: which artboard, which State Machine, which properties, and what should happen if the request fails?&lt;/p&gt;

&lt;p&gt;Those questions reveal a delivery gap. The animation may be finished visually, but the product interface is still undefined.&lt;/p&gt;

&lt;p&gt;A useful Rive mascot handoff gives the next developer enough information to load the character, control it, recover from failure, and update it later. It also gives the founder a concrete way to decide whether the work is complete.&lt;/p&gt;

&lt;p&gt;This checklist is for teams commissioning or integrating interactive app mascots, onboarding characters, and AI companions. The example names and ranges are proposed conventions, not requirements imposed by Rive. Use them to build your own delivery agreement before production starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Separate editable source from the runtime file
&lt;/h2&gt;

&lt;p&gt;Start by asking for two different deliverables: the source you can maintain and the asset your application can load.&lt;/p&gt;

&lt;p&gt;Rive exports a &lt;code&gt;.riv&lt;/code&gt; file for runtime use. Its backup format, &lt;code&gt;.rev&lt;/code&gt;, preserves information that is stripped from the runtime export. That distinction matters when you need to change the artwork or animation later. See Rive’s official guides to &lt;a href="https://rive.app/docs/editor/exporting/exporting-for-runtime" rel="noopener noreferrer"&gt;runtime export&lt;/a&gt; and &lt;a href="https://rive.app/docs/editor/exporting/exporting-for-backup" rel="noopener noreferrer"&gt;backup export&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Request access to the editable project or an appropriate backup, plus the final runtime file. Confirm that the arrangement also covers any external artwork, fonts, images, or audio required by the delivered design. Do not assume that receiving a binary export transfers access to everything used to create it.&lt;/p&gt;

&lt;p&gt;Use a release name that connects these deliverables. For example, the project revision, exported asset, and documentation might all reference &lt;code&gt;assistant-v1.2&lt;/code&gt;. The exact naming scheme is less important than being able to answer, “Which source produced the file currently in production?”&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Specify the entry point precisely
&lt;/h2&gt;

&lt;p&gt;A developer should not need to open every artboard to find the intended character.&lt;/p&gt;

&lt;p&gt;Document the exact artboard name, State Machine name, intended default configuration, and expected initial pose. Include the character’s intended display size and the fit/alignment behavior for narrow and wide containers.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asset: assistant-v1.2.riv
Artboard: ProductAssistant
State Machine: AssistantController
View Model: AssistantData
Initial activity: idle
Initial gaze: centered
Initial mouth: closed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These identifiers form part of the integration contract. Treat a public-name change as a coordinated change to both the file and its host code.&lt;/p&gt;

&lt;p&gt;Rive allows one exported asset to be used across supported runtimes, but compatibility still depends on the features and runtime versions involved. A file loading successfully is only the beginning of verification; you must also check that the intended behavior is present.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Deliver a control schema, not a list of animations
&lt;/h2&gt;

&lt;p&gt;“Idle, happy, wave, talk” is an animation inventory. It does not explain how the application should request those behaviors.&lt;/p&gt;

&lt;p&gt;For a new integration, define a small public data interface. Rive’s Data Binding system connects View Model data to scene properties; View Model instances hold the actual values. The official &lt;a href="https://rive.app/docs/editor/data-binding/overview" rel="noopener noreferrer"&gt;Data Binding overview&lt;/a&gt; explains this separation.&lt;/p&gt;

&lt;p&gt;An example handoff schema could look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Accepted values&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;activity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;Integer 0–4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Conversation controller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mood&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;Integer 0–2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Product state adapter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mouthOpen&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;0–1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Audio controller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lookX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;-1–1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Attention controller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lookY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;-1–1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Attention controller&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Below the table, define every discrete value. For this example, activity might mean idle, listening, thinking, speaking, or unavailable. Explain whether unsupported values are rejected, clamped, or mapped to a fallback.&lt;/p&gt;

&lt;p&gt;Also document units. A value of &lt;code&gt;0.5&lt;/code&gt; could mean half-open, half a second, or halfway across an artboard. Developers should never have to infer the meaning from a property name.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Decide who can write each value
&lt;/h2&gt;

&lt;p&gt;Many apparently random animation bugs come from competing updates rather than a broken rig.&lt;/p&gt;

&lt;p&gt;Imagine an idle timer sets &lt;code&gt;activity&lt;/code&gt; to idle while the audio player sets it to speaking. Both updates are valid locally, but only one reflects the overall product state. The handoff should establish one application owner for that decision.&lt;/p&gt;

&lt;p&gt;A practical division is to let application logic own business state and let the Rive system own the visual response. The app decides that a submission succeeded. The character decides how the success gesture looks.&lt;/p&gt;

&lt;p&gt;Document any values that flow back from the character. If a tap inside the artboard can request an action, distinguish the request from the action’s successful completion. A visual event must not be treated as proof that a network operation finished.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Write transition rules as observable behavior
&lt;/h2&gt;

&lt;p&gt;“Smooth transitions” is too vague to test. Describe the conditions that cause a transition and what can interrupt it.&lt;/p&gt;

&lt;p&gt;For each primary activity, answer three questions: what enters it, what exits it, and which events take priority? An assistant that is speaking should normally respond immediately to cancellation. A celebratory gesture should not prevent the user from starting a new interaction.&lt;/p&gt;

&lt;p&gt;An example rule is: “When playback is cancelled, stop mouth updates, close the mouth, and select the current conversation activity. Ignore completion callbacks belonging to the cancelled utterance.” This is specific enough for a developer to implement and for a reviewer to exercise.&lt;/p&gt;

&lt;p&gt;Keep the animation’s timing separate from the network’s timing. A thinking loop should tolerate an unknown wait. Avoid assuming that an answer always arrives before a fixed animation finishes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native.&lt;/p&gt;

&lt;p&gt;View live work and request an estimate at &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;. Send your project brief on &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Make lip-sync requirements explicit
&lt;/h2&gt;

&lt;p&gt;If the character speaks, the handoff needs more than a “talk” animation.&lt;/p&gt;

&lt;p&gt;Specify whether the mouth uses a simple speaking loop, an audio-level envelope, or timed viseme changes. These are different deliverables. An amplitude-driven mouth conveys speaking activity, but it does not identify the mouth shape associated with each speech sound.&lt;/p&gt;

&lt;p&gt;For timed visemes, include the supported mouth poses, their IDs, the expected timestamp units, and the mapping from the speech system’s output. State what happens when timing data is missing or an unfamiliar label arrives.&lt;/p&gt;

&lt;p&gt;Define the clock used for synchronization. A sequence based on audio playback position can behave differently from one based on when network messages arrive. Test buffering and interruption deliberately.&lt;/p&gt;

&lt;p&gt;Finally, specify ownership of the mouth. If a facial expression and the speech system both animate the same deformation, document how they combine or which one wins. This decision belongs in the asset design as well as the host integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Include a loading and lifecycle plan
&lt;/h2&gt;

&lt;p&gt;The person integrating the character must know when it is safe to access its properties and who releases the associated resources.&lt;/p&gt;

&lt;p&gt;Write down the expected loading sequence: load the asset, create the appropriate controller, bind an instance, obtain property references, apply the latest application snapshot, and display the ready character.&lt;/p&gt;

&lt;p&gt;Rive’s runtime guides provide platform-specific APIs. The &lt;a href="https://rive.app/docs/runtimes/web/rive-parameters" rel="noopener noreferrer"&gt;Web parameters reference&lt;/a&gt;, &lt;a href="https://rive.app/docs/runtimes/flutter/flutter" rel="noopener noreferrer"&gt;Flutter guide&lt;/a&gt;, and &lt;a href="https://rive.app/docs/runtimes/react-native/react-native" rel="noopener noreferrer"&gt;React Native guide&lt;/a&gt; should be linked from the handoff rather than replaced with an unqualified “works everywhere.”&lt;/p&gt;

&lt;p&gt;Record resource ownership separately from visual state. Reusing loaded file data does not mean that two visible characters should share the same mutable activity and expression. Explain the intended sharing boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Test the exported file in the actual hosts
&lt;/h2&gt;

&lt;p&gt;An editor preview proves that the design works in the editor. It does not prove that the selected runtime, renderer, and device combination supports every feature being used.&lt;/p&gt;

&lt;p&gt;Ask for runtime notes that identify the package version, renderer, operating system, device or browser, and test outcome. Avoid a single ambiguous checkbox labelled “mobile tested.”&lt;/p&gt;

&lt;p&gt;Use the same short event sequence on each target:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load from a fresh application start.&lt;/li&gt;
&lt;li&gt;Enter listening, then thinking.&lt;/li&gt;
&lt;li&gt;Begin speaking and change gaze.&lt;/li&gt;
&lt;li&gt;Interrupt speech before it finishes.&lt;/li&gt;
&lt;li&gt;Trigger a recoverable failure.&lt;/li&gt;
&lt;li&gt;Retry and complete the interaction.&lt;/li&gt;
&lt;li&gt;Leave the screen and return.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Include a missing-asset test and an out-of-range input test. Acceptance should cover both the expected path and at least the failures most likely to affect your product.&lt;/p&gt;

&lt;p&gt;If performance matters, ask for the measurement method and environment alongside any result. “Runs smoothly” is a subjective observation. A reproducible profile on the supported device tier is more useful than an unexplained frame-rate number.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Define the fallback outside the character
&lt;/h2&gt;

&lt;p&gt;A failed character asset should not make the product unusable.&lt;/p&gt;

&lt;p&gt;Keep meaningful status text and essential controls in the host interface. A static image or empty decorative area may be an acceptable visual fallback; an invisible Stop button is not.&lt;/p&gt;

&lt;p&gt;For an assistant, preserve the transcript and retry path even when animation fails. For onboarding, allow the user to continue without waiting for the mascot to load.&lt;/p&gt;

&lt;p&gt;Also agree on reduced-motion behavior. It might reduce idle movement while retaining a concise success indication, or use a static pose throughout. React Native exposes motion-preference information through &lt;a href="https://reactnative.dev/docs/accessibilityinfo" rel="noopener noreferrer"&gt;AccessibilityInfo&lt;/a&gt;; the product still needs an explicit policy for how the character responds.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Use a small acceptance document
&lt;/h2&gt;

&lt;p&gt;The best checklist is one your team can actually complete during handoff. Put the evidence next to each requirement.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Deliverable&lt;/th&gt;
&lt;th&gt;Acceptance evidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Editable project or backup&lt;/td&gt;
&lt;td&gt;Receiving team can access and maintain it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime &lt;code&gt;.riv&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Release identifier matches the documented source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artboard and State Machine&lt;/td&gt;
&lt;td&gt;Exact names confirmed in each target integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public controls&lt;/td&gt;
&lt;td&gt;Types, ranges, defaults, and owners documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transitions&lt;/td&gt;
&lt;td&gt;Interruptions and recovery exercised&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech behavior&lt;/td&gt;
&lt;td&gt;Timing format and missing-data fallback tested&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifecycle&lt;/td&gt;
&lt;td&gt;Loading, disposal, and return-to-screen behavior checked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accessibility&lt;/td&gt;
&lt;td&gt;Text status and reduced-motion behavior reviewed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime coverage&lt;/td&gt;
&lt;td&gt;Versions and environments recorded&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Add a named owner for unresolved items. A known limitation can be acceptable if everyone understands it before release. An undocumented limitation becomes a surprise for the next developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions before signing off
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is the &lt;code&gt;.riv&lt;/code&gt; file enough?&lt;/strong&gt; It can be enough to run the character, but it is not the whole maintenance and integration package. Ask separately for editable source access, dependencies, and documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can the same file serve Web, Flutter, and React Native?&lt;/strong&gt; That is a reasonable design target across supported runtimes. Validate the actual feature set on the chosen versions instead of assuming identical behavior from the file extension alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the animator need to build the whole app?&lt;/strong&gt; No. A clear scope can stop at an integration-ready asset and a small demonstration. If production integration is required, name the screens, platforms, and acceptance tests explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When is specialist help useful?&lt;/strong&gt; When character rigging, layered behavior, speech synchronization, and host lifecycle decisions overlap. A specialist can help make those interfaces consistent before the work spreads across multiple people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Send a brief a developer can estimate
&lt;/h2&gt;

&lt;p&gt;For &lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;Mascot Engine’s interactive character services&lt;/a&gt;, a useful brief includes the target platforms, existing artwork, required states, speaking requirements, deadline, and expected handoff depth. Mention whether your team already has a Rive asset that needs repair or wants a new character system.&lt;/p&gt;

&lt;p&gt;Include one concrete user journey: “The user asks a question, interrupts the answer, then retries offline.” That reveals more about the work than a long list of adjectives describing personality.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt; Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native. Explore &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;live work and request an estimate&lt;/a&gt;, or &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;send your project brief on WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>webdev</category>
      <category>flutter</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>How to Build an Interactive AI Assistant Avatar for Web, Flutter and React Native</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:11:36 +0000</pubDate>
      <link>https://dev.to/uianimation/how-to-build-an-interactive-ai-assistant-avatar-for-web-flutter-and-react-native-2n1e</link>
      <guid>https://dev.to/uianimation/how-to-build-an-interactive-ai-assistant-avatar-for-web-flutter-and-react-native-2n1e</guid>
      <description>&lt;p&gt;An AI assistant avatar is not just a looping video. It is a visible interface to an asynchronous system: microphone capture, model responses, speech playback, interruptions, and failures.&lt;/p&gt;

&lt;p&gt;If the character keeps talking after the user presses Stop, the animation is communicating the wrong product state. If it celebrates before an action succeeds, it creates the wrong expectation. A convincing avatar starts with reliable behavior, then adds personality.&lt;/p&gt;

&lt;p&gt;For founders and developers building a web product, Flutter app, React Native experience, or SaaS assistant, the useful question is: &lt;strong&gt;what contract connects the character to the application?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This guide proposes a practical architecture using Rive State Machines, six named controls, and a shared runtime asset. The state names and numeric ranges below are design recommendations, not built-in Rive conventions. You can adapt them to your product without coupling the animation to one AI provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rive fits live product states
&lt;/h2&gt;

&lt;p&gt;A video has a predetermined sequence. A live assistant needs to change direction when something happens: the user interrupts, audio stalls, a request fails, or the interface loses focus.&lt;/p&gt;

&lt;p&gt;Rive State Machines let designers connect animation states through conditional transitions. Layers can separate behaviors such as body motion and facial response. That makes it possible to author reusable reactions instead of exporting a video for every combination. See Rive’s &lt;a href="https://rive.app/docs/editor/state-machine/state-machine" rel="noopener noreferrer"&gt;State Machine overview&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The important boundary is that your application owns the conversation and business logic. It decides whether a request succeeded and whether audio is actually playing. Rive presents that decision through motion; it should not become your networking or conversation controller.&lt;/p&gt;

&lt;p&gt;Treat “lightweight” as a measurable target, not a guarantee. Budget the &lt;code&gt;.riv&lt;/code&gt; asset, runtime download, external assets, memory, and frame time together. A simple vector character can still become expensive when the scene accumulates unnecessary complexity. Rive’s &lt;a href="https://rive.app/docs/runtimes/getting-started" rel="noopener noreferrer"&gt;runtime introduction&lt;/a&gt; also cautions that feature availability depends on the runtime and renderer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with seven essential states
&lt;/h2&gt;

&lt;p&gt;Before rigging a character, write down what each state means and which application event ends it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Product meaning&lt;/th&gt;
&lt;th&gt;Suggested visual behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;idle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ready for the next interaction&lt;/td&gt;
&lt;td&gt;Quiet breathing, occasional blink&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;listening&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Microphone capture is active&lt;/td&gt;
&lt;td&gt;Attentive posture, restrained input response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;thinking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Waiting for an answer or preparing playback&lt;/td&gt;
&lt;td&gt;Small recurring motion that tolerates unknown duration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;speaking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Assistant audio is playing&lt;/td&gt;
&lt;td&gt;Mouth motion with controlled facial expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;success&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The requested operation has completed successfully&lt;/td&gt;
&lt;td&gt;Brief acknowledgement, then return to the appropriate state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;error/offline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The interaction cannot continue normally&lt;/td&gt;
&lt;td&gt;Calm concern, accompanied by a useful text message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sleeping&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The assistant is deliberately inactive&lt;/td&gt;
&lt;td&gt;Resting pose with minimal movement&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These meanings matter more than the animation style. Microphone permission alone does not mean listening. Receiving the first text token does not mean speaking. A completed answer does not prove that a requested database update succeeded.&lt;/p&gt;

&lt;p&gt;Define transition priority explicitly. An error or cancellation should interrupt speaking; a success gesture should not delay a new listening session. Use interruptible transitions where responsiveness matters, and reserve longer transitions for moments that cannot block interaction.&lt;/p&gt;

&lt;p&gt;For an initial implementation, allow one primary activity at a time. Keep emotion and gaze separate. That avoids multiplying states into combinations such as “happy-speaking-looking-left” and makes the design easier to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a clean input architecture
&lt;/h2&gt;

&lt;p&gt;There is an important terminology update: Rive recommends &lt;strong&gt;Data Binding and View Models&lt;/strong&gt; for new projects. Legacy State Machine Inputs still appear in older integrations, but they are no longer the preferred starting point. View Model properties can drive transitions and other bound elements. Read the official &lt;a href="https://rive.app/docs/editor/data-binding/overview" rel="noopener noreferrer"&gt;Data Binding overview&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here, “inputs” means the public controls your application supplies. Implement them as exported View Model properties for a new system, with a documented adapter if you must support an older file.&lt;/p&gt;

&lt;p&gt;For example, name the artboard &lt;code&gt;Assistant&lt;/code&gt;, the State Machine &lt;code&gt;AssistantSM&lt;/code&gt;, and the View Model &lt;code&gt;AssistantVM&lt;/code&gt;. The following deliberately uses numeric properties to keep the example contract simple; enum properties are another option when supported by your selected runtime versions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Control&lt;/th&gt;
&lt;th&gt;Proposed values&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;activity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Integer 0–6&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0 idle, 1 listening, 2 thinking, 3 speaking, 4 success, 5 error/offline, 6 sleeping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;emotion&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Integer 0–3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0 neutral, 1 warm, 2 pleased, 3 concerned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;viseme&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Integer 0–7&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Project-specific mouth shape; 0 is rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;audioLevel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number 0–1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Smoothed level of the active audio source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lookX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number -1–1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Horizontal gaze; positive means character’s screen-right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lookY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Number -1–1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Vertical gaze; positive means down on screen&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Validate values before writing them. Reject invalid activity IDs, clamp continuous controls, and map unknown mouth shapes to rest. Document whether numeric choices are discrete selectors or blend values: interpolating between activity IDs should never accidentally select an unrelated state.&lt;/p&gt;

&lt;p&gt;Give each property one owner. The conversation controller owns &lt;code&gt;activity&lt;/code&gt;; the speech controller owns mouth timing; the pointer or attention controller owns gaze. Otherwise, an idle timer can overwrite a speaking update while audio is still playing.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    A[AI event] --&amp;gt; B[Application logic]
    B --&amp;gt; C[Rive State Machine input]
    C --&amp;gt; D[Character response]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;For a new file, the diagram’s input step is a View Model property update that drives a State Machine transition. A speech-start event becomes &lt;code&gt;activity = 3&lt;/code&gt;; playback completion resets the mouth and selects the next activity.&lt;/p&gt;

&lt;p&gt;Use a conversation or utterance ID to discard late events. After cancellation, a delayed completion callback from the previous utterance must not reset a new listening session. Store the latest complete control snapshot so a newly loaded character can immediately catch up with the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native.&lt;/p&gt;

&lt;p&gt;View live work and request an estimate at &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Send your project brief on &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;WhatsApp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the right speaking system
&lt;/h2&gt;

&lt;p&gt;There are two useful levels of mouth animation. Choose based on the speech data your application can actually provide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audio-driven speaking
&lt;/h3&gt;

&lt;p&gt;For a simple assistant, derive a normalized amplitude envelope from the assistant’s output audio. Smooth abrupt changes and map that value to jaw opening or a speaking blend.&lt;/p&gt;

&lt;p&gt;This communicates activity without requiring phoneme timing. It is not phonetic lip sync: loudness cannot tell you whether the speaker is forming an “M” or an “O.” Avoid choosing random mouth shapes and describing the result as accurate synchronization.&lt;/p&gt;

&lt;p&gt;Use output audio for speaking and microphone audio only for listening feedback. Gate mouth movement on actual playback. During silence, buffering, cancellation, or playback failure, return the mouth to rest rather than leaving the last open pose visible.&lt;/p&gt;

&lt;p&gt;Specify which animation owns mouth opening. If &lt;code&gt;audioLevel&lt;/code&gt; and &lt;code&gt;viseme&lt;/code&gt; both drive the same deformation independently, they can conflict. A sensible contract uses one speaking mode at a time, or explicitly defines amplitude as a small modulation of a selected mouth pose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Viseme lip sync
&lt;/h3&gt;

&lt;p&gt;A viseme is a visible mouth pose associated with speech sounds. Several sounds can share a pose, so the character usually needs fewer visual shapes than there are phonemes.&lt;/p&gt;

&lt;p&gt;Prepare a small mouth library with rest, closed lips, wide, rounded, and other shapes suited to the design. Then document the mapping from the speech system’s timing labels to your &lt;code&gt;viseme&lt;/code&gt; IDs. The proposed 0–7 range is only an example; choose the actual set with your animator.&lt;/p&gt;

&lt;p&gt;Your speech or alignment system must provide the timing data. This architecture does not assume that loading a &lt;code&gt;.riv&lt;/code&gt; file automatically extracts visemes from arbitrary audio.&lt;/p&gt;

&lt;p&gt;Schedule changes against the audio playback position, not the arrival time of network chunks. For streamed speech, account for each chunk’s offset and any buffering. Briefly blend compatible shapes where useful, while preserving important closures. Test pauses, rapid speech, interruption, and the end of every utterance.&lt;/p&gt;

&lt;p&gt;If timing data is unavailable, fall back to amplitude-driven speaking or a restrained speaking loop. Keep the same &lt;code&gt;activity&lt;/code&gt; contract so the rest of the product remains predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add gaze without making it distracting
&lt;/h2&gt;

&lt;p&gt;Convert a pointer position or UI attention target into normalized character coordinates. Clamp &lt;code&gt;lookX&lt;/code&gt; and &lt;code&gt;lookY&lt;/code&gt;, ease toward the target, and return to center when the target disappears.&lt;/p&gt;

&lt;p&gt;Gaze should support attention: toward the microphone during listening, toward a relevant result after completion, or toward the user during speech. It does not require camera-based eye tracking.&lt;/p&gt;

&lt;p&gt;On touch devices, use a tap target or product event instead of assuming a continuously moving cursor exists. Test the gaze after resizing and changing character placement; screen coordinates and artboard coordinates are not interchangeable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepare one .riv system for three platforms
&lt;/h2&gt;

&lt;p&gt;The reusable unit is the exported asset plus its behavioral contract. The host integrations remain platform-specific. Choose runtime versions and renderers first, then validate the same exported file on every target. Do not infer mobile compatibility solely from the editor preview.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web
&lt;/h3&gt;

&lt;p&gt;Load the file, choose the artboard and State Machine, bind the default View Model instance, and obtain property references only after loading completes.&lt;/p&gt;

&lt;p&gt;For example, inside a Web runtime load callback, an adapter can cache a property and update it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Requires a loaded Rive instance with autoBind: true,&lt;/span&gt;
&lt;span class="c1"&gt;// an exported default View Model instance, and a number property.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;riveInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;viewModelInstance&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;activity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;activity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing avatar activity property&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showSpeaking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This illustrates the &lt;a href="https://rive.app/docs/runtimes/web/data-binding" rel="noopener noreferrer"&gt;Web Data Binding API&lt;/a&gt;, not a complete voice assistant. Your application still manages audio, readiness, errors, and cancellation.&lt;/p&gt;

&lt;p&gt;Handle canvas sizing, asset-load failure, and cleanup when the component unmounts. Rive’s &lt;a href="https://rive.app/docs/runtimes/web/rive-parameters" rel="noopener noreferrer"&gt;Web parameters reference&lt;/a&gt; documents artboard selection, State Machine selection, automatic binding, and lifecycle APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flutter
&lt;/h3&gt;

&lt;p&gt;Use the current Rive Flutter integration appropriate to your project. Rive documents file loaders, &lt;code&gt;RiveWidgetBuilder&lt;/code&gt;, and &lt;code&gt;RiveWidgetController&lt;/code&gt; in its &lt;a href="https://rive.app/docs/runtimes/flutter/flutter" rel="noopener noreferrer"&gt;Flutter runtime guide&lt;/a&gt;; its &lt;a href="https://rive.app/docs/runtimes/flutter/data-binding" rel="noopener noreferrer"&gt;Flutter Data Binding guide&lt;/a&gt; explains accessing and binding View Model instances.&lt;/p&gt;

&lt;p&gt;Create and retain the loader and controller at the correct widget lifecycle boundary. Follow the selected API’s ownership and disposal rules. Keep audio-level updates localized instead of rebuilding the entire screen for each sample.&lt;/p&gt;

&lt;p&gt;Flutter’s &lt;a href="https://docs.flutter.dev/perf/best-practices" rel="noopener noreferrer"&gt;performance guidance&lt;/a&gt; recommends avoiding costly repeated work in &lt;code&gt;build()&lt;/code&gt; and limiting rebuild scope. Profile the actual screen with the avatar, scrolling, and audio active together, especially on the lowest device tier you support.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Native
&lt;/h3&gt;

&lt;p&gt;Rive’s current &lt;a href="https://rive.app/docs/runtimes/react-native/react-native" rel="noopener noreferrer"&gt;React Native setup guide&lt;/a&gt; uses &lt;code&gt;@rive-app/react-native&lt;/code&gt; and requires Nitro Modules. Check the documented React Native, native OS, and build-tool requirements before integrating it into an existing app.&lt;/p&gt;

&lt;p&gt;Use that runtime’s file loading, view, and View Model APIs to implement the same six controls. Avoid mixing snippets from the legacy package with current APIs; Rive provides a &lt;a href="https://rive.app/docs/runtimes/react-native/migration-guide" rel="noopener noreferrer"&gt;migration guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Connect foreground/background changes to your playback policy using React Native’s &lt;a href="https://reactnative.dev/docs/appstate" rel="noopener noreferrer"&gt;AppState API&lt;/a&gt;. On resume, synchronize from current application state instead of blindly replaying an old speaking animation.&lt;/p&gt;

&lt;p&gt;Across platforms, show textual status and preserve usable controls even if the character cannot load. Offer reduced motion and avoid conveying errors through expression alone. React Native’s &lt;a href="https://reactnative.dev/docs/accessibilityinfo" rel="noopener noreferrer"&gt;AccessibilityInfo API&lt;/a&gt; exposes reduced-motion preferences and change notifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer handoff checklist
&lt;/h2&gt;

&lt;p&gt;Ask for a package that another developer can integrate without reverse-engineering the editor file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Editable .riv source requirement, clarified:&lt;/strong&gt; request editable Rive project access or a &lt;code&gt;.rev&lt;/code&gt; backup &lt;strong&gt;and&lt;/strong&gt; the runtime-ready &lt;code&gt;.riv&lt;/code&gt;. Rive distinguishes its &lt;a href="https://rive.app/docs/editor/exporting/exporting-for-backup" rel="noopener noreferrer"&gt;editable backup export&lt;/a&gt; from its &lt;a href="https://rive.app/docs/editor/exporting/exporting-for-runtime" rel="noopener noreferrer"&gt;runtime export&lt;/a&gt;; a runtime &lt;code&gt;.riv&lt;/code&gt; alone is not the complete editable source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artboard name:&lt;/strong&gt; exact spelling, dimensions, intended fit, and alignment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Machine name:&lt;/strong&gt; exact exported identifier and initial behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Named inputs:&lt;/strong&gt; property names, types, View Model name, default instance, and any legacy adapter mapping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Valid ranges:&lt;/strong&gt; discrete values, continuous bounds, viseme mapping, and coordinate conventions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default values:&lt;/strong&gt; initial activity, neutral emotion, closed mouth, silent level, and centered gaze.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transition rules:&lt;/strong&gt; priorities, interruptions, gesture completion, timeouts, and recovery behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime test notes:&lt;/strong&gt; tested package versions, renderers, devices, load behavior, and known limitations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fallback state:&lt;/strong&gt; safe idle or static image on asset failure, with errors explained in the surrounding UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before acceptance, replay a small event sequence: load, listen, think, speak, interrupt, fail, retry, and background/resume. Include missing visemes and a slow network. Confirm that cancellation stops both audio and mouth movement, and that stale events cannot change the next interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to hire a specialist
&lt;/h2&gt;

&lt;p&gt;Bring in a specialist when the work spans character design, rigging, layered State Machines, mouth-pose design, and runtime integration. The difficult part is often making those pieces agree under interruption, not producing an attractive idle animation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mascotengine.com/services/" rel="noopener noreferrer"&gt;Mascot Engine’s interactive character services&lt;/a&gt; cover Rive mascots, AI characters, rigging, State Machines, viseme lip sync, gaze controls, Data Binding/ViewModels, runtime-ready files, and developer documentation for Web, Flutter, and React Native.&lt;/p&gt;

&lt;p&gt;For a useful estimate, send your target platforms, existing artwork, required states, speech provider or sample timing data, expected character size, deadline, and budget range. Mention whether your developers need integration support or only documented assets. Those details help define a realistic scope before animation begins.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By Praneeth Kawya Thathsara, founder of Mascot Engine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Need an interactive Rive character for your product?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mascot Engine creates app mascots, AI companions, State Machines, lip sync, and developer-ready Rive systems for Web, Flutter, and React Native.&lt;/p&gt;

&lt;p&gt;View live work and request an estimate at &lt;a href="https://mascotengine.com/" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Send your project brief on &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;WhatsApp&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rive</category>
      <category>flutter</category>
      <category>reactnative</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built a Rive Skill for AI Coding Agents — SKILL.md for Codex, ChatGPT, Cursor &amp; Gemini</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Mon, 31 Aug 2026 18:17:24 +0000</pubDate>
      <link>https://dev.to/uianimation/i-built-a-rive-skill-for-ai-coding-agents-skillmd-for-codex-chatgpt-cursor-gemini-4pm6</link>
      <guid>https://dev.to/uianimation/i-built-a-rive-skill-for-ai-coding-agents-skillmd-for-codex-chatgpt-cursor-gemini-4pm6</guid>
      <description>&lt;h1&gt;
  
  
  I Built an Open-Source Rive Skill for AI Coding Agents
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm0joxsg9ouyshvryz5kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm0joxsg9ouyshvryz5kr.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI coding agents are getting much better at building apps.&lt;/p&gt;

&lt;p&gt;But there is still a problem when the task involves &lt;strong&gt;Rive&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can ask an AI tool to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;integrate a &lt;code&gt;.riv&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;create State Machine logic&lt;/li&gt;
&lt;li&gt;connect runtime inputs&lt;/li&gt;
&lt;li&gt;work with Data Binding&lt;/li&gt;
&lt;li&gt;debug an animation&lt;/li&gt;
&lt;li&gt;optimize a Rive component&lt;/li&gt;
&lt;li&gt;prepare a developer handoff&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and the answer may look convincing.&lt;/p&gt;

&lt;p&gt;But Rive evolves quickly.&lt;/p&gt;

&lt;p&gt;An AI model may remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an older runtime API&lt;/li&gt;
&lt;li&gt;outdated SDK syntax&lt;/li&gt;
&lt;li&gt;old State Machine patterns&lt;/li&gt;
&lt;li&gt;incomplete Data Binding behavior&lt;/li&gt;
&lt;li&gt;a renderer option that changed&lt;/li&gt;
&lt;li&gt;generic animation advice that does not match production Rive workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I created:&lt;/p&gt;

&lt;h1&gt;
  
  
  Rive Skill
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Production-ready Rive guidance for AI coding agents&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;GitHub:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/uianimation/rive-skill" rel="noopener noreferrer"&gt;https://github.com/uianimation/rive-skill&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Download SKILL.md directly:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/uianimation/rive-skill/raw/refs/heads/main/SKILL.md" rel="noopener noreferrer"&gt;https://github.com/uianimation/rive-skill/raw/refs/heads/main/SKILL.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give AI agents a maintainable Rive-specific instruction layer instead of forcing them to rely only on generic model knowledge.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h1&gt;
  
  
  Why AI Agents Need Rive-Specific Guidance
&lt;/h1&gt;

&lt;p&gt;Rive is not just another animation file format.&lt;/p&gt;

&lt;p&gt;A production Rive project can include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artboards
Timelines
Bones
Meshes
Constraints
Components
Layouts
State Machines
Listeners
Events
Data Binding
View Models
Converters
Nested Artboards
Runtime APIs
Renderers
Scripting
Rive MCP
Accessibility
Performance Constraints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a lot of system behavior for an AI coding assistant to reason about correctly.&lt;/p&gt;

&lt;p&gt;And the problem becomes more serious when an animation moves from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Looks good in the Rive Editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Works correctly in the actual product
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are not the same thing.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Real Problem: Rive Handoff Is a System Problem
&lt;/h1&gt;

&lt;p&gt;A Rive animator can create a beautiful animation.&lt;/p&gt;

&lt;p&gt;A developer can have the correct SDK installed.&lt;/p&gt;

&lt;p&gt;And the integration can still fail.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because production Rive work needs a clear contract between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Designer
   ↓
Rive Animator
   ↓
.riv Architecture
   ↓
Developer
   ↓
Runtime
   ↓
Application State
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, imagine a voice assistant character.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.riv&lt;/code&gt; file may contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idle
Listening
Thinking
Speaking
Success
Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application may need inputs such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity
emotion
isSpeaking
audioLevel
lookX
lookY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the AI coding agent does not understand that contract, it may try to solve the problem by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;swapping animations manually&lt;/li&gt;
&lt;li&gt;creating unnecessary state logic&lt;/li&gt;
&lt;li&gt;assuming input names&lt;/li&gt;
&lt;li&gt;resetting the State Machine incorrectly&lt;/li&gt;
&lt;li&gt;controlling visual layers directly from application code&lt;/li&gt;
&lt;li&gt;rebuilding logic already handled inside Rive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That creates fragile integrations.&lt;/p&gt;




&lt;h1&gt;
  
  
  What the Rive Skill Does
&lt;/h1&gt;

&lt;p&gt;The project organizes Rive guidance into three main areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Authoring
&lt;/h2&gt;

&lt;p&gt;Guidance around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artboards
Timelines
Rigging
Components
Layouts
Assets
Naming
Structure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to help an AI agent reason about how the &lt;code&gt;.riv&lt;/code&gt; file itself should be organized.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Interaction
&lt;/h2&gt;

&lt;p&gt;Guidance around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;State Machines
Listeners
Data Binding
View Models
Converters
Runtime-controlled values
Interaction architecture
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where Rive becomes more than a linear animation.&lt;/p&gt;

&lt;p&gt;Instead of thinking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Play animation A
then animation B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the agent can think in terms of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application State
      ↓
Rive Inputs / Data
      ↓
Character / UI Behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Integration
&lt;/h2&gt;

&lt;p&gt;Guidance around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Runtimes
Renderers
Scripting
Rive MCP
Performance
Accessibility
Developer Handoff
Debugging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly important because most real Rive problems happen outside the animation timeline.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I Did Not Put Everything in One Huge SKILL.md
&lt;/h1&gt;

&lt;p&gt;One large instruction file sounds convenient.&lt;/p&gt;

&lt;p&gt;But it creates another problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;context overload.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An AI agent working on a Flutter runtime bug does not need every detail about character rigging.&lt;/p&gt;

&lt;p&gt;An agent helping with a Rive character rig does not necessarily need the full web renderer discussion.&lt;/p&gt;

&lt;p&gt;So the repository uses focused references.&lt;/p&gt;

&lt;p&gt;The structure currently looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rive-skill/
├── SKILL.md
├── agents/
│   └── openai.yaml
├── assets/
│   ├── rive-skill-icon.svg
│   └── rive-skill-community-cover.png
├── evals/
│   └── behavioral-cases.md
├── references/
│   ├── editor-authoring.md
│   ├── interaction-data.md
│   ├── scripting-ai-mcp.md
│   ├── runtimes-performance-accessibility.md
│   ├── runtime-integration-patterns.md
│   ├── runtime-handoff-checklist.md
│   └── official-docs-map.md
├── scripts/
│   ├── build-portable.ps1
│   └── validate-skill.ps1
└── rive-instructions.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the main skill can stay relatively focused while deeper guidance remains available when needed.&lt;/p&gt;




&lt;h1&gt;
  
  
  SKILL.md vs rive-instructions.md
&lt;/h1&gt;

&lt;p&gt;The repository includes two useful ways to consume the guidance.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;SKILL.md&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Best for tools that support agent skills directly.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Codex
Agent Skills-compatible clients
Agent workflows with skill discovery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;rive-instructions.md&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Best for prompt-based workflows.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ChatGPT
Cursor
Gemini
Other AI coding assistants
Custom agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The portable file bundles the deeper references so the model does not lose important specialist instructions.&lt;/p&gt;




&lt;h1&gt;
  
  
  Install the Rive Skill in Codex
&lt;/h1&gt;

&lt;p&gt;For a personal skill available across projects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; rive-skill ~/.codex/skills/rive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a project-specific installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; rive-skill .codex/skills/rive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then invoke it explicitly as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or allow Codex to select it when the request matches the skill description.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example: Without a Rive Skill
&lt;/h1&gt;

&lt;p&gt;Imagine prompting an AI coding agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My Rive animation is not responding correctly in React.
Fix the State Machine integration.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without enough project context, the agent might immediately start rewriting runtime code.&lt;/p&gt;

&lt;p&gt;But the actual problem could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wrong artboard name
Wrong State Machine name
Wrong input type
Wrong input path
Default state mismatch
Nested input path issue
Data Binding mismatch
Old runtime syntax
Missing event listener
Incorrect lifecycle handling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The correct debugging process is not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Guess
↓
Rewrite
↓
Try again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should be closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Verify Runtime
↓
Verify Asset
↓
Verify Artboard
↓
Verify State Machine
↓
Verify Inputs
↓
Verify Runtime Contract
↓
Verify Application State
↓
Only then change implementation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This debugging discipline is one of the things the skill is designed to encourage.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example: AI Character State Machine
&lt;/h1&gt;

&lt;p&gt;Suppose an app contains an interactive Rive mascot.&lt;/p&gt;

&lt;p&gt;The runtime contract might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artboard:
Mascot

State Machine:
MascotController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity
0 = idle
1 = listening
2 = thinking
3 = speaking

emotion
0 = neutral
1 = happy
2 = concerned

isPending
boolean

audioLevel
0.0 → 1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A weak implementation may create application code like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if speaking:
    play speaking animation

if happy:
    play happy animation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that can conflict immediately.&lt;/p&gt;

&lt;p&gt;What if the character is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Speaking + Happy + Looking Left
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A better Rive architecture allows independent systems to coexist.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Activity → body state
Emotion → expression
AudioLevel → speaking intensity
LookX/Y → eye/head direction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application sends data.&lt;/p&gt;

&lt;p&gt;Rive decides how the animation behaves.&lt;/p&gt;




&lt;h1&gt;
  
  
  State Machines Are Not Just Animation Playlists
&lt;/h1&gt;

&lt;p&gt;This distinction is important.&lt;/p&gt;

&lt;p&gt;A Rive State Machine should not always be treated as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Animation A
→ Animation B
→ Animation C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can represent interactive product logic.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Button
├── Default
├── Hover
├── Press
├── Loading
├── Success
└── Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or a mascot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mascot
├── Idle
├── Listening
├── Thinking
├── Speaking
├── Celebrate
├── Sleep
└── Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or an onboarding component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step
├── Locked
├── Available
├── Active
└── Complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI agent needs to understand the animation as a component, not simply as a video.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Runtime Contracts Matter
&lt;/h1&gt;

&lt;p&gt;One of the most useful things you can give a developer is a small contract.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FILE
assistant.riv

ARTBOARD
Assistant

STATE MACHINE
AssistantController

INPUTS

activity: number
0 idle
1 listening
2 thinking
3 speaking

isPending: boolean

confirmed: trigger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEFAULT STATE
Idle

EXPECTED RESTING APPEARANCE
Blue

LOOPING STATES
Idle
Listening
Pending

ONE-SHOT STATES
Confirmed
Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tiny document can save hours of back-and-forth.&lt;/p&gt;

&lt;p&gt;The Rive Skill includes developer-handoff guidance because animation architecture and integration architecture are connected.&lt;/p&gt;




&lt;h1&gt;
  
  
  Semantic Naming Matters More Than It Looks
&lt;/h1&gt;

&lt;p&gt;Compare this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Animation 1
Animation 2
Boolean 1
Trigger
Shape 43
Group 21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idle
Listening
isPending
triggerConfirmed
Mouth
Head
LeftArm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second version is not just easier for humans.&lt;/p&gt;

&lt;p&gt;It is also easier for AI agents.&lt;/p&gt;

&lt;p&gt;AI tools perform better when your project exposes &lt;strong&gt;semantic structure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Meaningful names improve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Debugging
Documentation
Runtime integration
AI-assisted coding
Future maintenance
Team handoff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  AI Makes Good Naming Even More Important
&lt;/h1&gt;

&lt;p&gt;Before AI coding agents, bad naming mostly frustrated developers.&lt;/p&gt;

&lt;p&gt;Now it also reduces the quality of machine reasoning.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input1 = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tells an AI almost nothing.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;isPending = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;provides intent.&lt;/p&gt;

&lt;p&gt;Likewise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;triggerConfirmed.fire()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;contains much more useful semantic information than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger3.fire()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As software development becomes increasingly AI-assisted, semantic animation architecture becomes more valuable.&lt;/p&gt;




&lt;h1&gt;
  
  
  Rive Data Binding and View Models
&lt;/h1&gt;

&lt;p&gt;Modern Rive workflows increasingly involve application data, not only animation triggers.&lt;/p&gt;

&lt;p&gt;A character may need values like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;username
progress
theme
level
emotion
avatarVariant
notificationCount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of hardcoding visual decisions in application code, those values can participate in a more structured Rive data architecture.&lt;/p&gt;

&lt;p&gt;The skill therefore includes guidance around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data Binding
View Models
View Model Instances
Converters
Runtime-controlled properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of the areas where generic AI answers can become outdated quickly, so version-sensitive behavior should be verified against current Rive documentation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Freshness Matters
&lt;/h1&gt;

&lt;p&gt;A static AI answer has a hidden problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It may have been correct once.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rive runtimes change.&lt;/p&gt;

&lt;p&gt;Documentation changes.&lt;/p&gt;

&lt;p&gt;Feature support changes.&lt;/p&gt;

&lt;p&gt;APIs change.&lt;/p&gt;

&lt;p&gt;Platform behavior changes.&lt;/p&gt;

&lt;p&gt;That means a production-focused skill should distinguish between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stable architectural guidance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Version-sensitive technical claims
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rive Skill includes an official documentation map and uses a research date so current behavior can be checked instead of blindly trusting remembered APIs.&lt;/p&gt;




&lt;h1&gt;
  
  
  Rive MCP and AI-Assisted Workflows
&lt;/h1&gt;

&lt;p&gt;Another interesting direction is &lt;strong&gt;Rive MCP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As design and development tools expose more structured interfaces to AI agents, an agent may eventually be able to inspect more of a Rive project directly instead of reasoning only from screenshots and descriptions.&lt;/p&gt;

&lt;p&gt;That creates workflows like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer Request
      ↓
AI Agent
      ↓
Inspect Rive Structure
      ↓
Understand State Machine
      ↓
Check Runtime Contract
      ↓
Suggest / Apply Integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But access to tools does not automatically mean good decisions.&lt;/p&gt;

&lt;p&gt;An AI agent still needs rules about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What to inspect first
What should not be changed
Which contract must be preserved
What requires current documentation
What counts as verified evidence
What should be handed back to the developer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is another reason I think skill files are useful.&lt;/p&gt;




&lt;h1&gt;
  
  
  Validation Matters Too
&lt;/h1&gt;

&lt;p&gt;The repository does not rely only on manually reading the skill.&lt;/p&gt;

&lt;p&gt;It also includes deterministic validation.&lt;/p&gt;

&lt;p&gt;You can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;/scripts/build-portable.ps1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;/scripts/validate-skill.ps1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And optionally include live documentation-link checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;/scripts/validate-skill.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-CheckExternalLinks&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The validation workflow checks things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontmatter
Reference routing
Required resources
Agent metadata
Portable-file drift
Behavioral evaluation configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That matters because instruction repositories can slowly become inconsistent as they grow.&lt;/p&gt;




&lt;h1&gt;
  
  
  Behavioral Evaluations
&lt;/h1&gt;

&lt;p&gt;There is also a behavioral test manifest.&lt;/p&gt;

&lt;p&gt;The idea is to test whether the agent makes the right kind of decision in situations such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No tool access
Partial MCP failure
Runtime uncertainty
Contract preservation
Current documentation verification
Evidence labeling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is different from testing whether the model can memorize one API.&lt;/p&gt;

&lt;p&gt;The goal is to test whether it behaves safely and usefully when working on a real Rive project.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Skill Is Open Source
&lt;/h1&gt;

&lt;p&gt;The project is released under the MIT License.&lt;/p&gt;

&lt;p&gt;That means developers, animators and AI-tool builders can inspect it, adapt it and contribute improvements.&lt;/p&gt;

&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/uianimation/rive-skill" rel="noopener noreferrer"&gt;github.com/uianimation/rive-skill&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Direct SKILL.md:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/uianimation/rive-skill/raw/refs/heads/main/SKILL.md" rel="noopener noreferrer"&gt;Download SKILL.md&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you work with Rive regularly, starring the repository also makes it easier to find again as the guidance evolves.&lt;/p&gt;




&lt;h1&gt;
  
  
  Who This Is For
&lt;/h1&gt;

&lt;p&gt;I think this project is useful for several groups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rive Animators
&lt;/h2&gt;

&lt;p&gt;Especially if you hand &lt;code&gt;.riv&lt;/code&gt; files to developers and want AI coding tools to understand your file structure correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers
&lt;/h2&gt;

&lt;p&gt;If you use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React
Flutter
React Native
Web
iOS
Android
Game engines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and regularly integrate Rive assets.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Coding Agent Users
&lt;/h2&gt;

&lt;p&gt;Especially developers using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Codex
ChatGPT
Cursor
Gemini
Custom coding agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for Rive-related implementation work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teams Building Interactive Mascots
&lt;/h2&gt;

&lt;p&gt;Characters usually involve more complex contracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idle
Expressions
Gestures
Lip Sync
Reactions
Progress
State Machines
Data Binding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Structured guidance becomes even more useful there.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I Want This Project to Become
&lt;/h1&gt;

&lt;p&gt;I do not want this repository to become a giant collection of copied Rive documentation.&lt;/p&gt;

&lt;p&gt;Rive already has documentation.&lt;/p&gt;

&lt;p&gt;The useful layer is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Official Rive Documentation
          +
Production Experience
          +
Architecture Rules
          +
Debugging Order
          +
AI Agent Instructions
          =
Rive Skill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill should tell the AI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What should I think about?&lt;/p&gt;

&lt;p&gt;What should I verify?&lt;/p&gt;

&lt;p&gt;What should I preserve?&lt;/p&gt;

&lt;p&gt;Where should I look for current information?&lt;/p&gt;

&lt;p&gt;What should a production-ready result contain?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is more useful than duplicating every SDK reference.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Prompts to Try
&lt;/h1&gt;

&lt;p&gt;After adding the skill to your AI workflow, you could try prompts like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive Review this Rive React integration and identify why the State Machine input is not updating.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive Design a runtime contract for this interactive mascot before I hand the .riv file to the Flutter developer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive Review my artboard, State Machine and input naming strategy for developer handoff.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive Help me structure a Rive character with idle, listening, thinking, speaking and emotion layers without creating state explosion.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive Diagnose this Rive integration without changing the existing runtime contract.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$rive Check whether this Rive API example is still current before recommending it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Rive + AI Is Bigger Than Code Generation
&lt;/h1&gt;

&lt;p&gt;The interesting part is not simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI can write Rive integration code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The larger opportunity is that AI can potentially help across the whole workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Brief
↓
Architecture
↓
Character / UI Structure
↓
Rigging Decisions
↓
Interaction Design
↓
State Machine Design
↓
Runtime Contract
↓
Integration
↓
Debugging
↓
Optimization
↓
QA
↓
Handoff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But to do that reliably, the agent needs domain-specific context.&lt;/p&gt;

&lt;p&gt;That is what this project is experimenting with.&lt;/p&gt;




&lt;h1&gt;
  
  
  Need a Human Rive Animator Too?
&lt;/h1&gt;

&lt;p&gt;AI can help developers reason about Rive implementation.&lt;/p&gt;

&lt;p&gt;But there are still projects where you need someone to actually design, rig and animate the asset.&lt;/p&gt;

&lt;p&gt;If you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rive character animation&lt;/li&gt;
&lt;li&gt;interactive mascots&lt;/li&gt;
&lt;li&gt;character rigging&lt;/li&gt;
&lt;li&gt;UI animation&lt;/li&gt;
&lt;li&gt;State Machines&lt;/li&gt;
&lt;li&gt;responsive Rive components&lt;/li&gt;
&lt;li&gt;Data Binding setup&lt;/li&gt;
&lt;li&gt;developer-ready &lt;code&gt;.riv&lt;/code&gt; handoff&lt;/li&gt;
&lt;li&gt;debugging and optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you can also visit:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://riveanimator.com/" rel="noopener noreferrer"&gt;riveanimator.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The goal there is production-ready Rive work that can actually move into development rather than stopping at a visual demo.&lt;/p&gt;




&lt;h1&gt;
  
  
  Contributing
&lt;/h1&gt;

&lt;p&gt;If you find something outdated, incomplete or incorrect, contributions are welcome.&lt;/p&gt;

&lt;p&gt;Good contributions should ideally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Solve a concrete Rive problem
Reference current official Rive information
Avoid duplicating existing rules
Improve AI decision-making
Improve production handoff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/uianimation/rive-skill" rel="noopener noreferrer"&gt;github.com/uianimation/rive-skill&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;AI coding agents are becoming part of everyday software development.&lt;/p&gt;

&lt;p&gt;That means the quality of the instructions we give them matters.&lt;/p&gt;

&lt;p&gt;For Rive, I do not think the best solution is to ask a general-purpose model to remember every runtime detail forever.&lt;/p&gt;

&lt;p&gt;A better approach is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Strong base model
+
Current official documentation
+
Domain-specific skill
+
Clear runtime contract
+
Good semantic naming
+
Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That combination can make AI-assisted Rive work much more reliable.&lt;/p&gt;

&lt;p&gt;If you use &lt;strong&gt;Rive with Codex, ChatGPT, Cursor, Gemini or another coding agent&lt;/strong&gt;, try the project and let me know what is missing.&lt;/p&gt;

&lt;p&gt;⭐ &lt;strong&gt;GitHub:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/uianimation/rive-skill" rel="noopener noreferrer"&gt;https://github.com/uianimation/rive-skill&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rive</category>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Real-Time Lip Sync for Rive 2D Characters: Visemes, State Machines, AI Voice &amp; Production Setup</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Mon, 31 Aug 2026 18:02:27 +0000</pubDate>
      <link>https://dev.to/uianimation/real-time-lip-sync-for-rive-2d-characters-visemes-state-machines-ai-voice-production-setup-13ij</link>
      <guid>https://dev.to/uianimation/real-time-lip-sync-for-rive-2d-characters-visemes-state-machines-ai-voice-production-setup-13ij</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9c50e22ha4vydvrrz2dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9c50e22ha4vydvrrz2dm.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Voice AI is getting very good.&lt;/p&gt;

&lt;p&gt;The visual side often isn't.&lt;/p&gt;

&lt;p&gt;You can connect an application to OpenAI Realtime, ElevenLabs, Gemini Live, or another voice system and create a conversation that sounds natural — but if the character on screen simply opens and closes its mouth, the illusion breaks immediately.&lt;/p&gt;

&lt;p&gt;For a believable 2D AI character, you need more than audio playback.&lt;/p&gt;

&lt;p&gt;You need a complete pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Voice / Audio
      ↓
Audio Analysis
      ↓
Phoneme / Viseme Detection
      ↓
Viseme Values
      ↓
Rive Character Rig
      ↓
Mouth Interpolation
      ↓
Expressions + Blinks + Gestures
      ↓
Living Interactive Character
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This guide focuses on the part that is often missing from lip-sync tutorials:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you actually prepare a production-ready Rive character for real-time lip sync?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What phonemes and visemes actually are&lt;/li&gt;
&lt;li&gt;The mouth shapes a character needs&lt;/li&gt;
&lt;li&gt;How to build the mouth system in Rive&lt;/li&gt;
&lt;li&gt;State Machine vs Data Binding approaches&lt;/li&gt;
&lt;li&gt;How to avoid robotic lip sync&lt;/li&gt;
&lt;li&gt;How lip sync should coexist with expressions and gestures&lt;/li&gt;
&lt;li&gt;Performance considerations for web and mobile&lt;/li&gt;
&lt;li&gt;AI voice integration architecture&lt;/li&gt;
&lt;li&gt;Stylized and non-human mascot lip sync&lt;/li&gt;
&lt;li&gt;Production testing&lt;/li&gt;
&lt;li&gt;When you need a custom Rive character instead of a generic avatar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need a custom production-ready Rive mascot rather than building the character system yourself, &lt;strong&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;&lt;/strong&gt; creates interactive Rive characters, rigs, state machines, expressions, lip-sync systems and developer-ready &lt;code&gt;.riv&lt;/code&gt; files.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Why Simple Mouth Open/Close Animation Doesn't Work
&lt;/h1&gt;

&lt;p&gt;The most basic talking animation uses audio amplitude.&lt;/p&gt;

&lt;p&gt;When the voice gets louder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mouth = open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it gets quieter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mouth = closed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can work for a tiny game character or a decorative animation.&lt;/p&gt;

&lt;p&gt;But it does not look like speech.&lt;/p&gt;

&lt;p&gt;Consider these sounds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;M
F
O
A
TH
S
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your mouth forms completely different shapes for each one.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;M / B / P&lt;/strong&gt; require the lips to close&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F / V&lt;/strong&gt; bring the upper teeth toward the lower lip&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt; creates a rounded mouth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A&lt;/strong&gt; creates a wider open mouth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S / Z&lt;/strong&gt; keep the teeth relatively close&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TH&lt;/strong&gt; has its own recognizable tongue/teeth relationship&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Amplitude cannot understand those differences.&lt;/p&gt;

&lt;p&gt;That is why realistic 2D lip sync usually works with &lt;strong&gt;visemes&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Phonemes vs Visemes
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;phoneme&lt;/strong&gt; represents a unit of sound.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;viseme&lt;/strong&gt; represents how a group of speech sounds looks visually on the mouth.&lt;/p&gt;

&lt;p&gt;Several phonemes can share one viseme.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/p/
/b/
/m/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;sound different, but visually all three involve the lips closing.&lt;/p&gt;

&lt;p&gt;So they can share a similar mouth position.&lt;/p&gt;

&lt;p&gt;This is important because a character does not need a unique drawing for every possible speech sound.&lt;/p&gt;

&lt;p&gt;Instead, we create a smaller collection of meaningful mouth poses and interpolate between them.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. A Practical Viseme Set for Rive Characters
&lt;/h1&gt;

&lt;p&gt;One widely referenced system is the Meta/Oculus viseme set.&lt;/p&gt;

&lt;p&gt;A production character can use mouth targets such as:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Viseme&lt;/th&gt;
&lt;th&gt;Typical Sound Group&lt;/th&gt;
&lt;th&gt;Visual Direction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sil&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;silence&lt;/td&gt;
&lt;td&gt;relaxed neutral mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;p, b, m&lt;/td&gt;
&lt;td&gt;lips pressed together&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FF&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;f, v&lt;/td&gt;
&lt;td&gt;upper teeth touching lower lip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;th&lt;/td&gt;
&lt;td&gt;tongue/teeth position&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;t, d&lt;/td&gt;
&lt;td&gt;slightly open articulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;k, g&lt;/td&gt;
&lt;td&gt;open rear articulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ch, j, sh&lt;/td&gt;
&lt;td&gt;forward compressed mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;s, z&lt;/td&gt;
&lt;td&gt;teeth close together&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;n, l&lt;/td&gt;
&lt;td&gt;relaxed open articulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;r&lt;/td&gt;
&lt;td&gt;rounded/contracted mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;aa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;td&gt;wide open mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;E&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;e&lt;/td&gt;
&lt;td&gt;wider horizontal mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;I&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ih&lt;/td&gt;
&lt;td&gt;smaller stretched mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;O&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;oh&lt;/td&gt;
&lt;td&gt;rounded mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;U&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;oo&lt;/td&gt;
&lt;td&gt;tighter rounded mouth&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You may see systems described as having 15 or 16 positions depending on whether the neutral/silence pose is counted separately.&lt;/p&gt;

&lt;p&gt;The important thing is &lt;strong&gt;not the marketing number&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The important thing is that the character artwork and runtime mapping agree on exactly what each value means.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. You Don't Always Need Every Viseme
&lt;/h1&gt;

&lt;p&gt;This is especially important for stylized mascots.&lt;/p&gt;

&lt;p&gt;A realistic human face may benefit from a detailed viseme set.&lt;/p&gt;

&lt;p&gt;A tiny cartoon robot probably doesn't.&lt;/p&gt;

&lt;p&gt;A practical setup might look like this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple mascot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Neutral
Closed
Wide
Open
Round
Teeth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Standard conversational character
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8–12 meaningful mouth positions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  High-fidelity conversational character
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Full viseme set
+ tongue
+ teeth
+ jaw
+ expression compensation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More mouth shapes do &lt;strong&gt;not automatically produce better animation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The quality of the rig and transitions matters just as much.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Designing the Character Before Opening Rive
&lt;/h1&gt;

&lt;p&gt;One of the biggest mistakes is building the character first and thinking about lip sync later.&lt;/p&gt;

&lt;p&gt;For voice-driven characters, the face should be designed for animation.&lt;/p&gt;

&lt;p&gt;The mouth area may need separate elements for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upper Lip
Lower Lip
Mouth Interior
Teeth
Tongue
Jaw
Cheeks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not every design needs every layer.&lt;/p&gt;

&lt;p&gt;A flat mascot might only require:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mouth Shape
Mouth Interior
Teeth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is keeping enough separation to create convincing deformation.&lt;/p&gt;

&lt;p&gt;This is one area where a specialist character workflow matters.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;&lt;/strong&gt;, interactive mascot artwork can be designed specifically around the final Rive rig instead of treating animation as an afterthought.&lt;/p&gt;

&lt;p&gt;That makes later additions such as talking, expressions, props, gestures and additional states much easier.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Two Ways to Build Mouth Shapes in Rive
&lt;/h1&gt;

&lt;p&gt;There are two broad approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method A — Separate Mouth Shapes
&lt;/h2&gt;

&lt;p&gt;Create separate vector artwork for different mouth positions.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mouth_sil
mouth_PP
mouth_FF
mouth_TH
mouth_DD
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then control visibility or blend between states.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to understand&lt;/li&gt;
&lt;li&gt;Easy to art-direct&lt;/li&gt;
&lt;li&gt;Good for highly stylized characters&lt;/li&gt;
&lt;li&gt;Individual shapes can look very different&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;More artwork&lt;/li&gt;
&lt;li&gt;More layers&lt;/li&gt;
&lt;li&gt;Transitions can look like swapping images if poorly implemented&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Method B — One Deformable Mouth Rig
&lt;/h2&gt;

&lt;p&gt;Build a reusable mouth using vector paths, bones, constraints or controlled deformation.&lt;/p&gt;

&lt;p&gt;Then create mouth poses from the same underlying structure.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Neutral
   ↓
Closed
   ↓
Wide
   ↓
Open
   ↓
Round
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The geometry transitions between positions rather than simply switching artwork.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Smoother transitions&lt;/li&gt;
&lt;li&gt;Smaller visual system&lt;/li&gt;
&lt;li&gt;Easier interpolation&lt;/li&gt;
&lt;li&gt;Better for expressive characters&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Harder to rig correctly&lt;/li&gt;
&lt;li&gt;Bad topology can create ugly deformation&lt;/li&gt;
&lt;li&gt;Extreme mouth shapes may require additional corrective artwork&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many production mascots, a &lt;strong&gt;hybrid approach&lt;/strong&gt; works best.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Recommended Rive Structure
&lt;/h1&gt;

&lt;p&gt;Keep the runtime structure predictable.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Character
├── Body
├── Head
│   ├── Eyes
│   ├── Brows
│   └── Mouth
│       ├── MouthInterior
│       ├── Teeth
│       ├── Tongue
│       └── LipRig
├── Arms
└── Accessories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then keep runtime controls logically separated.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CharacterController

Speech
├── viseme
├── speaking
└── speechIntensity

Expression
├── emotion
├── blink
└── lookDirection

Behavior
├── idle
├── gesture
└── reaction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact names are flexible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistency is not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your developer should be able to understand the &lt;code&gt;.riv&lt;/code&gt; contract without opening every animation manually.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. State Machines and Data Binding
&lt;/h1&gt;

&lt;p&gt;Modern Rive applications are not limited to playing linear animations.&lt;/p&gt;

&lt;p&gt;Runtime code can control character behavior through Rive's interactive systems.&lt;/p&gt;

&lt;p&gt;A useful architecture is to separate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Speech
Expression
Behavior
Appearance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of creating one giant state machine containing every possible combination.&lt;/p&gt;

&lt;p&gt;For example, a voice assistant might conceptually expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;viseme
speechIntensity
isSpeaking

emotion
lookX
lookY

activity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application can then update those values while Rive handles the visual result.&lt;/p&gt;

&lt;p&gt;With Rive Data Binding, runtime applications can read and update exposed properties through View Models and View Model Instances.&lt;/p&gt;

&lt;p&gt;This is particularly useful for reusable character systems because your application data can be separated from the visual implementation.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Do Not Build 15 Hard Cuts
&lt;/h1&gt;

&lt;p&gt;Imagine receiving:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PP
aa
O
SS
PP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and instantly switching the artwork every time.&lt;/p&gt;

&lt;p&gt;The result will look mechanical.&lt;/p&gt;

&lt;p&gt;Speech is continuous.&lt;/p&gt;

&lt;p&gt;Your animation needs &lt;strong&gt;coarticulation&lt;/strong&gt; — mouth movement naturally begins moving toward upcoming sounds while leaving previous ones.&lt;/p&gt;

&lt;p&gt;A simplified conceptual model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Previous Viseme
      ↓
Interpolation
      ↓
Current Viseme
      ↓
Interpolation
      ↓
Next Viseme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where Rive becomes particularly useful.&lt;/p&gt;

&lt;p&gt;Instead of treating every viseme as an isolated frame, the character can transition through a designed animation system.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. 120 FPS Is Not What Makes Lip Sync Good
&lt;/h1&gt;

&lt;p&gt;High frame rates sound impressive.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;120 FPS ≠ good lip sync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A badly designed mouth system at 120 FPS is still a badly designed mouth system.&lt;/p&gt;

&lt;p&gt;The biggest factors are usually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Viseme accuracy
+ timing
+ interpolation
+ coarticulation
+ character design
+ expression handling
+ audio synchronization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A well-designed system running at 60 FPS can look excellent.&lt;/p&gt;

&lt;p&gt;Frame rate should be treated as a performance characteristic, not as the primary measure of lip-sync quality.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. Audio-to-Character Architecture
&lt;/h1&gt;

&lt;p&gt;A typical real-time voice character architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ┌──────────────────────┐
                │   Voice AI / TTS     │
                │ OpenAI / ElevenLabs  │
                │ Gemini / Custom TTS  │
                └──────────┬───────────┘
                           │
                           ▼
                    Audio Playback
                           │
                           ▼
                    Audio Analysis
                           │
                           ▼
                  Viseme Detection
                           │
                           ▼
                   Viseme Timeline
                           │
                           ▼
                Rive Runtime Controller
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
            Mouth       Expression    Gesture
              │            │            │
              └────────────┼────────────┘
                           ▼
                    Final Character
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice something important:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI model should not directly control every visual layer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It should provide meaningful data.&lt;/p&gt;

&lt;p&gt;The animation system should decide how that data becomes motion.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. Separate Speech From Emotion
&lt;/h1&gt;

&lt;p&gt;A character can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Happy + Talking
Sad + Talking
Concerned + Talking
Excited + Talking
Neutral + Talking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your talking animation contains the entire face, you may accidentally overwrite the expression.&lt;/p&gt;

&lt;p&gt;Instead, think in layers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Layer 1 → Body / Idle
Layer 2 → Head movement
Layer 3 → Expression
Layer 4 → Eyes / Blink
Layer 5 → Mouth / Lip Sync
Layer 6 → Gesture / Reaction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now speech can continue while emotion changes.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity = speaking
emotion = happy
viseme = O
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could simultaneously produce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;happy eyebrows&lt;/li&gt;
&lt;li&gt;smiling eyes&lt;/li&gt;
&lt;li&gt;a speaking mouth&lt;/li&gt;
&lt;li&gt;subtle breathing&lt;/li&gt;
&lt;li&gt;occasional hand gestures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That feels much more like a character than a talking SVG.&lt;/p&gt;




&lt;h1&gt;
  
  
  13. The Neutral Mouth Is Extremely Important
&lt;/h1&gt;

&lt;p&gt;Do not underestimate &lt;code&gt;sil&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The neutral mouth is used during:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pauses&lt;/li&gt;
&lt;li&gt;breathing&lt;/li&gt;
&lt;li&gt;sentence breaks&lt;/li&gt;
&lt;li&gt;thinking&lt;/li&gt;
&lt;li&gt;waiting&lt;/li&gt;
&lt;li&gt;transitions between speech and idle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the system immediately snaps back to a perfectly static closed mouth after every word, the character feels robotic.&lt;/p&gt;

&lt;p&gt;A better system can transition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Speech
 ↓
Short pause
 ↓
Soft neutral
 ↓
Idle expression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The neutral mouth should also respect emotion.&lt;/p&gt;

&lt;p&gt;A happy neutral mouth and a sad neutral mouth may not be visually identical.&lt;/p&gt;




&lt;h1&gt;
  
  
  14. Add Speech Intensity
&lt;/h1&gt;

&lt;p&gt;Viseme ID tells us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What mouth shape should be visible?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it does not necessarily tell us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How strongly should that shape be expressed?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An optional value such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;speechIntensity = 0.0 → 1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can influence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jaw opening&lt;/li&gt;
&lt;li&gt;mouth exaggeration&lt;/li&gt;
&lt;li&gt;cheek movement&lt;/li&gt;
&lt;li&gt;head movement&lt;/li&gt;
&lt;li&gt;subtle body response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Quiet speech
speechIntensity = 0.25

Normal speech
speechIntensity = 0.55

Excited speech
speechIntensity = 0.90
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates much more personality than visemes alone.&lt;/p&gt;




&lt;h1&gt;
  
  
  15. Add Micro-Movements
&lt;/h1&gt;

&lt;p&gt;Perfect mouth synchronization can still feel dead if everything else freezes.&lt;/p&gt;

&lt;p&gt;During speech, consider subtle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blinking
Eye movement
Head movement
Breathing
Eyebrow reactions
Body weight shifts
Hand gestures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These should not be random chaos.&lt;/p&gt;

&lt;p&gt;They should be subtle secondary animation supporting the dialogue.&lt;/p&gt;

&lt;p&gt;The goal is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;animate everything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;remove the feeling that only the mouth is alive.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  16. Lip Sync for Non-Human Mascots
&lt;/h1&gt;

&lt;p&gt;This is where generic avatar systems often become limiting.&lt;/p&gt;

&lt;p&gt;What if your character is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a dog&lt;/li&gt;
&lt;li&gt;a fox&lt;/li&gt;
&lt;li&gt;a blob&lt;/li&gt;
&lt;li&gt;a flame&lt;/li&gt;
&lt;li&gt;a robot&lt;/li&gt;
&lt;li&gt;a floating orb&lt;/li&gt;
&lt;li&gt;a slash-shaped brand mascot&lt;/li&gt;
&lt;li&gt;a creature without human lips?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should &lt;strong&gt;not force human anatomy onto every mascot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead, translate speech into the visual language of that character.&lt;/p&gt;

&lt;p&gt;A robot might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LED mouth shapes
+ face panel deformation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A creature might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jaw
+ muzzle
+ tongue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A minimal mascot might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4–6 abstract mouth shapes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An orb could communicate speech through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Shape deformation
+ amplitude
+ glow
+ internal motion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why custom character rigging is often more valuable than simply attaching a generic lip-sync API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;&lt;/strong&gt; can build custom Rive mascots around the character's actual visual identity, including non-human characters where traditional human visemes would look wrong.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. Expressions Need Corrective Mouth Poses
&lt;/h1&gt;

&lt;p&gt;Here is a problem that appears later in production.&lt;/p&gt;

&lt;p&gt;Suppose your normal &lt;code&gt;aa&lt;/code&gt; mouth looks good.&lt;/p&gt;

&lt;p&gt;Now apply a big smile.&lt;/p&gt;

&lt;p&gt;The same mouth deformation may no longer look correct.&lt;/p&gt;

&lt;p&gt;You may need corrective behavior for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Happy + aa
Sad + aa
Concerned + O
Excited + PP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do not necessarily need to manually create every possible combination.&lt;/p&gt;

&lt;p&gt;Instead, design the rig so the base expression and viseme deformation can coexist.&lt;/p&gt;

&lt;p&gt;For high-quality character systems, this is often one of the most important parts of the rig.&lt;/p&gt;




&lt;h1&gt;
  
  
  18. Avoid State Explosion
&lt;/h1&gt;

&lt;p&gt;Suppose you have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;15 visemes
×
5 emotions
×
5 activity states
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That already gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;375 combinations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not create 375 separate animations.&lt;/p&gt;

&lt;p&gt;Build a layered system.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Viseme → mouth

Emotion → brows + eyes + mouth bias

Activity → body behavior

Intensity → exaggeration

Look direction → pupils/head
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final character is the combination of those systems.&lt;/p&gt;

&lt;p&gt;That is much more scalable.&lt;/p&gt;




&lt;h1&gt;
  
  
  19. Suggested Developer Contract
&lt;/h1&gt;

&lt;p&gt;Before handing a &lt;code&gt;.riv&lt;/code&gt; file to developers, document the runtime interface.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Artboard:
AICharacter

Controller:
CharacterController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Possible runtime properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;viseme
0–14

isSpeaking
boolean

speechIntensity
0.0–1.0

emotion
0 = neutral
1 = happy
2 = empathetic
3 = concerned
4 = surprised

activity
0 = idle
1 = listening
2 = thinking
3 = speaking
4 = error

lookX
-1.0–1.0

lookY
-1.0–1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is only an example.&lt;/p&gt;

&lt;p&gt;Your actual contract should match the application architecture.&lt;/p&gt;

&lt;p&gt;But documenting it prevents one of the most common Rive handoff problems:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The animation works in the Editor, but nobody knows how the app is supposed to control it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  20. Web and Mobile Performance
&lt;/h1&gt;

&lt;p&gt;A production voice character may be running alongside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rive
+
WebGL / renderer
+
Audio playback
+
Audio analysis
+
AI voice streaming
+
Application UI
+
Network communication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So optimization matters.&lt;/p&gt;

&lt;p&gt;Do not benchmark only on a powerful development machine.&lt;/p&gt;

&lt;p&gt;Test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Desktop Chrome
Safari
iPhone
Android
Older mobile hardware
Low-power mode
Different screen sizes
Long conversations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU
GPU
Memory
Battery usage
Thermals
Frame stability
Audio synchronization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A beautiful demo that overheats a phone after ten minutes is not production-ready.&lt;/p&gt;




&lt;h1&gt;
  
  
  21. Optimize the Rive File Too
&lt;/h1&gt;

&lt;p&gt;The lip-sync engine is only part of performance.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.riv&lt;/code&gt; file itself can become expensive.&lt;/p&gt;

&lt;p&gt;Watch for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unnecessary vector complexity&lt;/li&gt;
&lt;li&gt;excessive clipping&lt;/li&gt;
&lt;li&gt;too many nested artboards&lt;/li&gt;
&lt;li&gt;unnecessarily heavy effects&lt;/li&gt;
&lt;li&gt;unused assets&lt;/li&gt;
&lt;li&gt;oversized embedded images&lt;/li&gt;
&lt;li&gt;excessive simultaneous animations&lt;/li&gt;
&lt;li&gt;complicated deformation where a simpler rig would work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A production mascot should be designed for the target runtime from the beginning.&lt;/p&gt;

&lt;p&gt;This is another reason &lt;strong&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;Mascot Engine&lt;/a&gt;&lt;/strong&gt; focuses on developer-ready Rive character systems rather than only delivering animation videos.&lt;/p&gt;

&lt;p&gt;The final asset needs to work inside the product.&lt;/p&gt;




&lt;h1&gt;
  
  
  22. Language and Accent Testing Matters
&lt;/h1&gt;

&lt;p&gt;Do not assume that a lip-sync model performing well with one English speaker will perform equally well everywhere.&lt;/p&gt;

&lt;p&gt;Test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Different accents
Different speaking speeds
Male and female voices
Synthetic voices
Whispering
Excited speech
Children's voices where relevant
Multiple languages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For multilingual products, test the actual languages used by your audience.&lt;/p&gt;

&lt;p&gt;Some visual mouth positions are shared broadly, but phoneme inventories and pronunciation patterns vary between languages.&lt;/p&gt;

&lt;p&gt;Your character system should degrade gracefully when the input is imperfect.&lt;/p&gt;




&lt;h1&gt;
  
  
  23. Test With Difficult Words
&lt;/h1&gt;

&lt;p&gt;Do not test only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hello, how can I help you today?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Test sequences that expose mouth problems.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;baby
pepper
very
five
mother
think
zebra
school
round
beautiful
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then test fast sentences.&lt;/p&gt;

&lt;p&gt;Then slow speech.&lt;/p&gt;

&lt;p&gt;Then interruptions.&lt;/p&gt;

&lt;p&gt;Then silence.&lt;/p&gt;

&lt;p&gt;Then rapid AI responses.&lt;/p&gt;

&lt;p&gt;You are looking for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;missed closures
late closures
mouth popping
excessive jaw movement
bad O → wide transitions
teeth flickering
tongue popping
neutral-state snapping
expression conflicts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  24. Audio Synchronization Is More Important Than Maximum FPS
&lt;/h1&gt;

&lt;p&gt;Users are sensitive to the relationship between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what they hear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what they see
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not simply rendering frames quickly.&lt;/p&gt;

&lt;p&gt;The goal is keeping the mouth movement perceptually synchronized with the actual playback.&lt;/p&gt;

&lt;p&gt;When benchmarking a lip-sync solution, document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
Browser
Audio source
Model/runtime
Frame rate
Inference window
Average latency
Worst-case latency
Test duration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without that information, statements such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sub-10ms&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;120fps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;are difficult to evaluate meaningfully.&lt;/p&gt;




&lt;h1&gt;
  
  
  25. Pre-Rendered vs Real-Time Lip Sync
&lt;/h1&gt;

&lt;p&gt;These are different problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-rendered lip sync
&lt;/h2&gt;

&lt;p&gt;Best for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Marketing videos
Explainer videos
Pre-recorded content
Cinematics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system can process the complete audio before rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-time lip sync
&lt;/h2&gt;

&lt;p&gt;Best for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI assistants
Voice agents
Interactive mascots
Education apps
Games
Kiosks
Virtual companions
Customer support characters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The character has to respond while audio is happening.&lt;/p&gt;

&lt;p&gt;For these products, Rive is particularly useful because lip sync can be part of a larger interactive character system rather than being exported as a fixed video.&lt;/p&gt;




&lt;h1&gt;
  
  
  26. Rive vs Lottie for Conversational Characters
&lt;/h1&gt;

&lt;p&gt;Lottie is excellent for many predefined motion assets.&lt;/p&gt;

&lt;p&gt;But conversational characters require dynamic runtime behavior.&lt;/p&gt;

&lt;p&gt;You may need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idle
+
Listening
+
Thinking
+
Speaking
+
Emotion
+
Lip Sync
+
Blink
+
Look Direction
+
User Interaction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not simply a timeline playback problem.&lt;/p&gt;

&lt;p&gt;Rive's runtime-controlled animation architecture makes it much better suited to characters whose behavior changes continuously based on application state.&lt;/p&gt;




&lt;h1&gt;
  
  
  27. Think Beyond Lip Sync
&lt;/h1&gt;

&lt;p&gt;A believable AI mascot should not simply have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idle
Talking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider the entire conversation lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connecting
    ↓
Ready
    ↓
Listening
    ↓
Thinking
    ↓
Speaking
    ↓
Waiting
    ↓
Listening
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then layer emotion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Neutral
Happy
Empathetic
Concerned
Surprised
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then micro-interaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blink
Look
Tap reaction
Gesture
Celebrate
Error
Sleep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are no longer building a lip-sync animation.&lt;/p&gt;

&lt;p&gt;You are building a &lt;strong&gt;character system&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  28. Example AI Companion Architecture
&lt;/h1&gt;

&lt;p&gt;Imagine an AI companion built with Rive.&lt;/p&gt;

&lt;p&gt;The application receives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;activity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;speaking&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;emotion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;happy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;viseme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;speechIntensity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.68&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;lookX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;lookY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rive character interprets those values visually.&lt;/p&gt;

&lt;p&gt;The body knows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am speaking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The face knows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am happy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The mouth knows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Form the current O-like viseme.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The rig knows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Speech intensity is moderately high.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The eyes know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look slightly right and upward.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This separation makes the character reusable.&lt;/p&gt;

&lt;p&gt;The AI controls &lt;strong&gt;meaningful data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rive controls &lt;strong&gt;animation&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  29. Production Checklist
&lt;/h1&gt;

&lt;p&gt;Before shipping a Rive lip-sync character, check:&lt;/p&gt;

&lt;h3&gt;
  
  
  Artwork
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Mouth layers are properly separated&lt;/li&gt;
&lt;li&gt;[ ] Neutral mouth looks natural&lt;/li&gt;
&lt;li&gt;[ ] Teeth do not flicker&lt;/li&gt;
&lt;li&gt;[ ] Tongue is only visible when appropriate&lt;/li&gt;
&lt;li&gt;[ ] Extreme poses maintain the character design&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Visemes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Closed-lip sounds visibly close&lt;/li&gt;
&lt;li&gt;[ ] F/V reads correctly&lt;/li&gt;
&lt;li&gt;[ ] Rounded vowels are distinguishable&lt;/li&gt;
&lt;li&gt;[ ] Wide/open vowels are distinguishable&lt;/li&gt;
&lt;li&gt;[ ] Silence returns naturally to neutral&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Animation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] No hard popping between visemes&lt;/li&gt;
&lt;li&gt;[ ] Transitions feel smooth&lt;/li&gt;
&lt;li&gt;[ ] Fast speech remains readable&lt;/li&gt;
&lt;li&gt;[ ] Slow speech does not look exaggerated&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Expressions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Lip sync works while happy&lt;/li&gt;
&lt;li&gt;[ ] Lip sync works while sad/concerned&lt;/li&gt;
&lt;li&gt;[ ] Blinking does not interrupt speech&lt;/li&gt;
&lt;li&gt;[ ] Eye movement remains independent&lt;/li&gt;
&lt;li&gt;[ ] Gestures can run during speech&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Runtime
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Inputs/properties are documented&lt;/li&gt;
&lt;li&gt;[ ] Default values are correct&lt;/li&gt;
&lt;li&gt;[ ] Missing audio fails safely&lt;/li&gt;
&lt;li&gt;[ ] Character returns to idle correctly&lt;/li&gt;
&lt;li&gt;[ ] Long conversations remain stable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Desktop tested&lt;/li&gt;
&lt;li&gt;[ ] iOS tested&lt;/li&gt;
&lt;li&gt;[ ] Android tested&lt;/li&gt;
&lt;li&gt;[ ] CPU/GPU usage checked&lt;/li&gt;
&lt;li&gt;[ ] File size checked&lt;/li&gt;
&lt;li&gt;[ ] Audio sync checked&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  30. Building a Custom Rive Lip-Sync Character
&lt;/h1&gt;

&lt;p&gt;You can build this entire system internally if your team already has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a character designer&lt;/li&gt;
&lt;li&gt;a Rive animator&lt;/li&gt;
&lt;li&gt;Rive rigging experience&lt;/li&gt;
&lt;li&gt;runtime integration experience&lt;/li&gt;
&lt;li&gt;knowledge of state machines/data binding&lt;/li&gt;
&lt;li&gt;an audio/viseme pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But if your team already has the AI voice technology and the missing part is the &lt;strong&gt;character&lt;/strong&gt;, that is exactly where a specialized Rive mascot service can help.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mascot Engine
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mascot Engine&lt;/strong&gt; creates custom interactive mascot systems for apps, websites, AI products and games.&lt;/p&gt;

&lt;p&gt;Depending on the project, a character can include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Character Design
Rive Rigging
Idle Animation
Blinking
Expressions
Lip Sync / Viseme System
Listening State
Thinking State
Speaking State
Reactions
Gestures
State Machines
Data Binding Setup
Developer Handoff
Production .riv File
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is not simply to make a character move.&lt;/p&gt;

&lt;p&gt;The goal is to deliver a reusable character that developers can actually control from the product.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;https://mascotengine.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Email:&lt;/strong&gt; &lt;a href="mailto:riveanimator@gmail.com"&gt;riveanimator@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;WhatsApp:&lt;/strong&gt; &lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;Chat on WhatsApp&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  31. What to Send When Requesting a Rive Character
&lt;/h1&gt;

&lt;p&gt;If you contact a Rive animator or Mascot Engine, prepare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Character artwork or visual reference
2. App / website screenshots
3. Target platforms
4. Voice provider
5. Required character states
6. Required emotions
7. Whether lip sync is required
8. Whether the character needs props
9. Expected runtime controls
10. Delivery timeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do not already have a character design, that can be part of the character development process too.&lt;/p&gt;




&lt;h1&gt;
  
  
  32. Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Real-time lip sync is not simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Audio → Open Mouth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it is not simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Audio → Viseme ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A good interactive character requires the entire chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Audio
   ↓
Speech Analysis
   ↓
Viseme Detection
   ↓
Timing
   ↓
Rive Mouth Rig
   ↓
Interpolation
   ↓
Expression
   ↓
Secondary Motion
   ↓
Character Behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The technical lip-sync model solves only part of the problem.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;character rig and animation system determine what the user actually sees&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is especially important for branded mascots, AI companions and non-human characters where generic human avatar systems are not enough.&lt;/p&gt;

&lt;p&gt;Build the character as a system from the beginning.&lt;/p&gt;

&lt;p&gt;Separate speech from emotion.&lt;/p&gt;

&lt;p&gt;Separate emotion from behavior.&lt;/p&gt;

&lt;p&gt;Keep the runtime contract clean.&lt;/p&gt;

&lt;p&gt;Test on real devices.&lt;/p&gt;

&lt;p&gt;And optimize for believable motion rather than impressive benchmark numbers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Need a Custom Rive Character?
&lt;/h2&gt;

&lt;p&gt;If you're building an AI assistant, voice agent, app mascot, game character or interactive website character and need the Rive side built for production:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mascot Engine&lt;/strong&gt; can help with character design, Rive rigging, interactive animation, state machines, expressions, lip-sync preparation and developer-ready &lt;code&gt;.riv&lt;/code&gt; delivery.&lt;/p&gt;

&lt;p&gt;🌐 &lt;strong&gt;&lt;a href="https://mascotengine.com" rel="noopener noreferrer"&gt;mascotengine.com&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
📧 &lt;strong&gt;&lt;a href="mailto:riveanimator@gmail.com"&gt;riveanimator@gmail.com&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
💬 &lt;strong&gt;&lt;a href="https://wa.me/94717000999" rel="noopener noreferrer"&gt;WhatsApp: +94 71 700 0999&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building an AI product with a character? Bookmark this guide before designing the mascot — the decisions you make in the artwork stage can determine how good the final lip sync can become.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rive</category>
      <category>animation</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From PNG to Interactive Mascot: Building App Characters With Rive</title>
      <dc:creator>Praneeth Kawya Thathsara</dc:creator>
      <pubDate>Thu, 27 Aug 2026 10:08:45 +0000</pubDate>
      <link>https://dev.to/uianimation/from-png-to-interactive-mascot-building-app-characters-with-rive-39g9</link>
      <guid>https://dev.to/uianimation/from-png-to-interactive-mascot-building-app-characters-with-rive-39g9</guid>
      <description>&lt;h1&gt;
  
  
  From PNG to Interactive Mascot: Building App Characters With Rive
&lt;/h1&gt;

&lt;p&gt;A lot of apps already have a mascot.&lt;/p&gt;

&lt;p&gt;The problem? It usually exists as a &lt;strong&gt;PNG, SVG, or static illustration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That works for a landing page, but inside an app, the character could do much more.&lt;/p&gt;

&lt;p&gt;Imagine your mascot reacting to real application states:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idle → Listening → Thinking → Speaking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading → Success → Celebration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of exporting dozens of GIFs or videos, I build these characters as &lt;strong&gt;interactive Rive systems&lt;/strong&gt; that developers can control directly from their applications.&lt;/p&gt;

&lt;p&gt;Here's how I do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start With the Existing PNG
&lt;/h2&gt;

&lt;p&gt;Yes — a PNG mascot can be enough to get started.&lt;/p&gt;

&lt;p&gt;But I normally don't animate the PNG directly.&lt;/p&gt;

&lt;p&gt;First, I recreate or prepare the character as animation-ready vector artwork and separate the parts that need to move:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Head&lt;/li&gt;
&lt;li&gt;Eyes&lt;/li&gt;
&lt;li&gt;Pupils&lt;/li&gt;
&lt;li&gt;Eyebrows&lt;/li&gt;
&lt;li&gt;Mouth&lt;/li&gt;
&lt;li&gt;Body&lt;/li&gt;
&lt;li&gt;Arms&lt;/li&gt;
&lt;li&gt;Legs&lt;/li&gt;
&lt;li&gt;Accessories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives us control over individual parts while keeping the original personality of the mascot.&lt;/p&gt;

&lt;p&gt;Sometimes hidden parts also need to be redrawn because they become visible during animation.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Build a Reusable Rive Rig
&lt;/h2&gt;

&lt;p&gt;Next comes rigging.&lt;/p&gt;

&lt;p&gt;I'm not only thinking about the animations the product needs today. I'm also thinking about what the character might need later.&lt;/p&gt;

&lt;p&gt;Version one might only need:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idle · Happy · Thinking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Later, the same mascot might need:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Walking · Sleeping · Speaking · Celebrating · Props · New Expressions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A reusable Rive rig makes expanding the character much easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Give the Character Life
&lt;/h2&gt;

&lt;p&gt;One of the first animations I usually create is the idle state.&lt;/p&gt;

&lt;p&gt;A good idle can include subtle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breathing&lt;/li&gt;
&lt;li&gt;Blinking&lt;/li&gt;
&lt;li&gt;Eye movement&lt;/li&gt;
&lt;li&gt;Body movement&lt;/li&gt;
&lt;li&gt;Secondary motion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to make the mascot constantly move.&lt;/p&gt;

&lt;p&gt;The goal is to make it feel alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Turn Animations Into App States
&lt;/h2&gt;

&lt;p&gt;Now things get interesting.&lt;/p&gt;

&lt;p&gt;For a normal SaaS or mobile app, we might have:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0 — Idle&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1 — Happy&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;2 — Loading&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;3 — Success&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;4 — Error&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;5 — Sleeping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For an AI app:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0 — Idle&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1 — Listening&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;2 — Thinking&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;3 — Speaking&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;4 — Error&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;5 — Sleeping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of manually selecting animation timelines, the application can simply communicate its current state.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Connect Everything With a Rive State Machine
&lt;/h2&gt;

&lt;p&gt;This is one of the reasons I like Rive for product animation.&lt;/p&gt;

&lt;p&gt;We can create a &lt;strong&gt;Rive State Machine&lt;/strong&gt; and expose simple inputs to developers.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;activity = 0 → Idle&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;activity = 1 → Listening&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;activity = 2 → Thinking&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;activity = 3 → Speaking&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;activity = 4 → Success&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;activity = 5 → Error&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application changes &lt;code&gt;activity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rive handles the visual behavior.&lt;/p&gt;

&lt;p&gt;We can also expose inputs such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;emotion&lt;/code&gt;&lt;br&gt;
&lt;code&gt;progress&lt;/code&gt;&lt;br&gt;
&lt;code&gt;audioLevel&lt;/code&gt;&lt;br&gt;
&lt;code&gt;lookX&lt;/code&gt;&lt;br&gt;
&lt;code&gt;lookY&lt;/code&gt;&lt;br&gt;
&lt;code&gt;isSleeping&lt;/code&gt;&lt;br&gt;
&lt;code&gt;tap&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now the mascot isn't just playing an animation.&lt;/p&gt;

&lt;p&gt;It's reacting to the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. AI Mascots Make This Even More Interesting
&lt;/h2&gt;

&lt;p&gt;Imagine a voice-first AI application.&lt;/p&gt;

&lt;p&gt;When the user starts talking:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listening&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the AI processes the request:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thinking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the AI responds:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speaking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When nothing is happening:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then we can add emotions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy · Empathetic · Concerned · Surprised&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can go further with lip sync, visemes, audio-level-driven movement and gaze controls.&lt;/p&gt;

&lt;p&gt;At that point, the mascot becomes the &lt;strong&gt;visual personality of the AI product&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. One Character Can Become a UI System
&lt;/h2&gt;

&lt;p&gt;A production mascot can eventually support:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product states:&lt;/strong&gt; Loading, Success, Error, Offline&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Character states:&lt;/strong&gt; Idle, Happy, Sad, Excited, Sleeping, Walking&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI states:&lt;/strong&gt; Listening, Thinking, Speaking&lt;/p&gt;

&lt;p&gt;You can also add different props, colors, outfits and expressions.&lt;/p&gt;

&lt;p&gt;That's why I prefer thinking about mascots as &lt;strong&gt;interactive systems&lt;/strong&gt;, not collections of separate animations.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Developer Handoff Matters
&lt;/h2&gt;

&lt;p&gt;A beautiful animation isn't enough if it's difficult to integrate.&lt;/p&gt;

&lt;p&gt;For production Rive projects, I focus on things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean artboard naming&lt;/li&gt;
&lt;li&gt;State Machine naming&lt;/li&gt;
&lt;li&gt;Predictable inputs&lt;/li&gt;
&lt;li&gt;Input value maps&lt;/li&gt;
&lt;li&gt;Smooth transitions&lt;/li&gt;
&lt;li&gt;File optimization&lt;/li&gt;
&lt;li&gt;Responsive behavior&lt;/li&gt;
&lt;li&gt;Future animation states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple setup could look like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artboard:&lt;/strong&gt; Mascot&lt;br&gt;
&lt;strong&gt;State Machine:&lt;/strong&gt; MascotController&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;activity:&lt;/strong&gt; 0–5&lt;br&gt;
&lt;strong&gt;emotion:&lt;/strong&gt; 0–3&lt;br&gt;
&lt;strong&gt;audioLevel:&lt;/strong&gt; 0.0–1.0&lt;br&gt;
&lt;strong&gt;lookX:&lt;/strong&gt; -1.0–1.0&lt;br&gt;
&lt;strong&gt;lookY:&lt;/strong&gt; -1.0–1.0&lt;br&gt;
&lt;strong&gt;tap:&lt;/strong&gt; Trigger&lt;/p&gt;

&lt;p&gt;The developer doesn't need to understand how every animation works internally.&lt;/p&gt;

&lt;p&gt;They only need to know how to control it.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. PNG → Interactive Mascot
&lt;/h2&gt;

&lt;p&gt;My typical workflow is:&lt;/p&gt;

&lt;p&gt;PNG / Illustration&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Vector Preparation&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Rive Character Rig&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Animation States&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Rive State Machine&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;App Logic&lt;/p&gt;

&lt;p&gt;↓&lt;/p&gt;

&lt;p&gt;Interactive Mascot&lt;/p&gt;

&lt;p&gt;The original mascot doesn't disappear.&lt;/p&gt;

&lt;p&gt;It simply becomes capable of responding to your product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building an App With a Mascot?
&lt;/h2&gt;

&lt;p&gt;I'm Praneeth Kawya Thathsara, a Rive animator specializing in interactive animation and character systems for apps.&lt;/p&gt;

&lt;p&gt;I work with &lt;strong&gt;indie developers, SaaS startups and AI product teams&lt;/strong&gt; building for Flutter, React Native, iOS, Android and the web.&lt;/p&gt;

&lt;p&gt;Even if your mascot currently exists only as a PNG, we can turn it into something interactive.&lt;/p&gt;

&lt;p&gt;Rive Animation: riveanimator.com&lt;br&gt;
Interactive Mascots &amp;amp; AI Characters: mascotengine.com&lt;br&gt;
Email: &lt;a href="mailto:riveanimator@gmail.com"&gt;riveanimator@gmail.com&lt;/a&gt;&lt;br&gt;
WhatsApp: +94 71 700 0999&lt;/p&gt;

&lt;p&gt;You build the product. I can help make it move.&lt;/p&gt;

</description>
      <category>png</category>
      <category>mascot</category>
      <category>animation</category>
      <category>rive</category>
    </item>
  </channel>
</rss>
