Have SMI have a back-pointer to its artboard instance
diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp
index 5b1629e..7e48cbb 100644
--- a/include/rive/animation/state_machine_instance.hpp
+++ b/include/rive/animation/state_machine_instance.hpp
@@ -21,6 +21,7 @@
 
     private:
         const StateMachine* m_Machine;
+        Artboard* m_ArtboardInstance;
         bool m_NeedsAdvance = false;
 
         size_t m_InputCount;
@@ -31,12 +32,12 @@
         void markNeedsAdvance();
 
     public:
-        StateMachineInstance(const StateMachine* machine);
+        StateMachineInstance(const StateMachine* machine, Artboard* instance);
         ~StateMachineInstance();
 
         // Advance the state machine by the specified time. Returns true if the
         // state machine will continue to animate after this advance.
-        bool advance(Artboard* artboard, float seconds);
+        bool advance(float seconds);
 
         // Returns true when the StateMachineInstance has more data to process.
         bool needsAdvance() const;
diff --git a/skia/viewer/src/main.cpp b/skia/viewer/src/main.cpp
index f0407bd..33a5593 100644
--- a/skia/viewer/src/main.cpp
+++ b/skia/viewer/src/main.cpp
@@ -66,7 +66,7 @@
     stateMachineInstance = nullptr;
 
     if (index >= 0 && index < artboard->stateMachineCount()) {
-        stateMachineInstance = new rive::StateMachineInstance(artboard->stateMachine(index));
+        stateMachineInstance = new rive::StateMachineInstance(artboard->stateMachine(index), artboard.get());
     }
 }
 
@@ -273,7 +273,7 @@
                 animationInstance->advance(elapsed);
                 animationInstance->apply(artboard.get());
             } else if (stateMachineInstance != nullptr) {
-                stateMachineInstance->advance(artboard.get(), elapsed);
+                stateMachineInstance->advance(elapsed);
             }
             artboard->advance(elapsed);
 
diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp
index e37dad3..5a7b8c6 100644
--- a/src/animation/state_machine_instance.cpp
+++ b/src/animation/state_machine_instance.cpp
@@ -213,7 +213,11 @@
     };
 } // namespace rive
 
-StateMachineInstance::StateMachineInstance(const StateMachine* machine) : m_Machine(machine) {
+StateMachineInstance::StateMachineInstance(const StateMachine* machine, Artboard* instance)
+        : m_Machine(machine)
+        , m_ArtboardInstance(instance)
+{
+    assert(instance->isInstance());
     m_InputCount = machine->inputCount();
     m_InputInstances = new SMIInput*[m_InputCount];
     for (size_t i = 0; i < m_InputCount; i++) {
@@ -255,10 +259,10 @@
     delete[] m_Layers;
 }
 
-bool StateMachineInstance::advance(Artboard* artboard, float seconds) {
+bool StateMachineInstance::advance(float seconds) {
     m_NeedsAdvance = false;
     for (size_t i = 0; i < m_LayerCount; i++) {
-        if (m_Layers[i].advance(artboard, seconds, m_InputInstances, m_InputCount)) {
+        if (m_Layers[i].advance(m_ArtboardInstance, seconds, m_InputInstances, m_InputCount)) {
             m_NeedsAdvance = true;
         }
     }
diff --git a/test/state_machine_test.cpp b/test/state_machine_test.cpp
index 92cc576..bd6196c 100644
--- a/test/state_machine_test.cpp
+++ b/test/state_machine_test.cpp
@@ -72,7 +72,8 @@
         }
     }
 
-    rive::StateMachineInstance smi(artboard->stateMachine("Button"));
+    auto abi = artboard->instance();
+    rive::StateMachineInstance smi(artboard->stateMachine("Button"), abi.get());
     REQUIRE(smi.getBool("Hover")->name() == "Hover");
     REQUIRE(smi.getBool("Press")->name() == "Press");
     REQUIRE(smi.getBool("Hover") != nullptr);
@@ -160,6 +161,6 @@
     auto animationState = layer->state(3)->as<rive::AnimationState>();
     REQUIRE(animationState->animation() == nullptr);
 
-    rive::StateMachineInstance smi(stateMachine);
-    smi.advance(artboard, 0.0f);
+    auto abi = artboard->instance();
+    rive::StateMachineInstance(stateMachine, abi.get()).advance(0.0f);
 }