Add backpointer to artboard to anim-instance
diff --git a/include/rive/animation/animation_state.hpp b/include/rive/animation/animation_state.hpp
index 178d287..f1a71b8 100644
--- a/include/rive/animation/animation_state.hpp
+++ b/include/rive/animation/animation_state.hpp
@@ -15,7 +15,7 @@
 
     public:
         const LinearAnimation* animation() const { return m_Animation; }
-        StateInstance* makeInstance() const override;
+        StateInstance* makeInstance(Artboard*) const override;
     };
 } // namespace rive
 
diff --git a/include/rive/animation/animation_state_instance.hpp b/include/rive/animation/animation_state_instance.hpp
index 57fce73..64d25bf 100644
--- a/include/rive/animation/animation_state_instance.hpp
+++ b/include/rive/animation/animation_state_instance.hpp
@@ -15,10 +15,10 @@
         bool m_KeepGoing;
 
     public:
-        AnimationStateInstance(const AnimationState* animationState);
+        AnimationStateInstance(const AnimationState* animationState, Artboard* instance);
 
         void advance(float seconds, SMIInput** inputs) override;
-        void apply(Artboard* artboard, float mix) override;
+        void apply(float mix) override;
 
         bool keepGoing() const override;
 
diff --git a/include/rive/animation/blend_state_1d.hpp b/include/rive/animation/blend_state_1d.hpp
index 72ceab6..8ffa1e4 100644
--- a/include/rive/animation/blend_state_1d.hpp
+++ b/include/rive/animation/blend_state_1d.hpp
@@ -12,7 +12,7 @@
 
         StatusCode import(ImportStack& importStack) override;
 
-        StateInstance* makeInstance() const override;
+        StateInstance* makeInstance(Artboard*) const override;
     };
 } // namespace rive
 
diff --git a/include/rive/animation/blend_state_1d_instance.hpp b/include/rive/animation/blend_state_1d_instance.hpp
index ccd2d15..db7e7a6 100644
--- a/include/rive/animation/blend_state_1d_instance.hpp
+++ b/include/rive/animation/blend_state_1d_instance.hpp
@@ -13,7 +13,7 @@
         int animationIndex(float value);
 
     public:
-        BlendState1DInstance(const BlendState1D* blendState);
+        BlendState1DInstance(const BlendState1D* blendState, Artboard* instance);
         void advance(float seconds, SMIInput** inputs) override;
     };
 } // namespace rive
diff --git a/include/rive/animation/blend_state_direct.hpp b/include/rive/animation/blend_state_direct.hpp
index 4dcb101..5562221 100644
--- a/include/rive/animation/blend_state_direct.hpp
+++ b/include/rive/animation/blend_state_direct.hpp
@@ -5,7 +5,7 @@
 namespace rive {
     class BlendStateDirect : public BlendStateDirectBase {
     public:
-        StateInstance* makeInstance() const override;
+        StateInstance* makeInstance(Artboard*) const override;
     };
 } // namespace rive
 
diff --git a/include/rive/animation/blend_state_direct_instance.hpp b/include/rive/animation/blend_state_direct_instance.hpp
index 032788d..fd90681 100644
--- a/include/rive/animation/blend_state_direct_instance.hpp
+++ b/include/rive/animation/blend_state_direct_instance.hpp
@@ -9,7 +9,7 @@
     class BlendStateDirectInstance
         : public BlendStateInstance<BlendStateDirect, BlendAnimationDirect> {
     public:
-        BlendStateDirectInstance(const BlendStateDirect* blendState);
+        BlendStateDirectInstance(const BlendStateDirect* blendState, Artboard* instance);
         void advance(float seconds, SMIInput** inputs) override;
     };
 } // namespace rive
diff --git a/include/rive/animation/blend_state_instance.hpp b/include/rive/animation/blend_state_instance.hpp
index 3b863bd..fe43e18 100644
--- a/include/rive/animation/blend_state_instance.hpp
+++ b/include/rive/animation/blend_state_instance.hpp
@@ -23,8 +23,10 @@
         const T* blendAnimation() const { return m_BlendAnimation; }
         const LinearAnimationInstance* animationInstance() const { return &m_AnimationInstance; }
 
-        BlendStateAnimationInstance(const T* blendAnimation) :
-            m_BlendAnimation(blendAnimation), m_AnimationInstance(blendAnimation->animation()) {}
+        BlendStateAnimationInstance(const T* blendAnimation, Artboard* instance) :
+            m_BlendAnimation(blendAnimation),
+            m_AnimationInstance(blendAnimation->animation(), instance)
+        {}
 
         void mix(float value) { m_Mix = value; }
     };
@@ -35,10 +37,10 @@
         bool m_KeepGoing = true;
 
     public:
-        BlendStateInstance(const K* blendState) : StateInstance(blendState) {
+        BlendStateInstance(const K* blendState, Artboard* instance) : StateInstance(blendState) {
             for (auto blendAnimation : blendState->animations()) {
                 m_AnimationInstances.emplace_back(
-                    BlendStateAnimationInstance<T>(static_cast<T*>(blendAnimation)));
+                    BlendStateAnimationInstance<T>(static_cast<T*>(blendAnimation), instance));
             }
         }
 
@@ -53,10 +55,10 @@
             }
         }
 
-        void apply(Artboard* artboard, float mix) override {
+        void apply(float mix) override {
             for (auto& animation : m_AnimationInstances) {
                 float m = mix * animation.m_Mix;
-                animation.m_AnimationInstance.apply(artboard, m);
+                animation.m_AnimationInstance.apply(m);
             }
         }
 
diff --git a/include/rive/animation/layer_state.hpp b/include/rive/animation/layer_state.hpp
index 3802da8..793947a 100644
--- a/include/rive/animation/layer_state.hpp
+++ b/include/rive/animation/layer_state.hpp
@@ -5,6 +5,7 @@
 #include <vector>
 
 namespace rive {
+    class Artboard;
     class StateTransition;
     class LayerStateImporter;
     class StateMachineLayerImporter;
@@ -35,7 +36,7 @@
 
         /// Make an instance of this state that can be advanced and applied by
         /// the state machine when it is active or being transitioned from.
-        virtual StateInstance* makeInstance() const;
+        virtual StateInstance* makeInstance(Artboard* instance) const;
     };
 } // namespace rive
 
diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp
index 31c1171..35c07d7 100644
--- a/include/rive/animation/linear_animation_instance.hpp
+++ b/include/rive/animation/linear_animation_instance.hpp
@@ -8,6 +8,7 @@
     class LinearAnimationInstance {
     private:
         const LinearAnimation* m_Animation = nullptr;
+        Artboard* m_ArtboardInstance;
         float m_Time;
         float m_TotalTime;
         float m_LastTotalTime;
@@ -17,7 +18,7 @@
         int m_LoopValue = -1;
 
     public:
-        LinearAnimationInstance(const LinearAnimation* animation);
+        LinearAnimationInstance(const LinearAnimation*, Artboard* instance);
 
         // Advance the animation by the specified time. Returns true if the
         // animation will continue to animate after this advance.
@@ -46,11 +47,11 @@
         // Sets the animation's point in time.
         void time(float value);
 
-        // Applies the animation instance to an artboard. The mix (a value
+        // Applies the animation instance to its artboard instance. The mix (a value
         // between 0 and 1) is the strength at which the animation is mixed with
         // other animations applied to the artboard.
-        void apply(Artboard* artboard, float mix = 1.0f) const {
-            m_Animation->apply(artboard, m_Time, mix);
+        void apply(float mix = 1.0f) const {
+            m_Animation->apply(m_ArtboardInstance, m_Time, mix);
         }
 
         // Set when the animation is advanced, true if the animation has stopped
diff --git a/include/rive/animation/nested_remap_animation.hpp b/include/rive/animation/nested_remap_animation.hpp
index 504ac0b..9303572 100644
--- a/include/rive/animation/nested_remap_animation.hpp
+++ b/include/rive/animation/nested_remap_animation.hpp
@@ -6,7 +6,7 @@
     class NestedRemapAnimation : public NestedRemapAnimationBase {
     public:
         void timeChanged() override;
-        void advance(float elapsedSeconds, Artboard* artboard) override;
+        void advance(float elapsedSeconds) override;
         void initializeAnimation(Artboard* artboard) override;
     };
 } // namespace rive
diff --git a/include/rive/animation/nested_simple_animation.hpp b/include/rive/animation/nested_simple_animation.hpp
index ceca0ce..3f0b0a2 100644
--- a/include/rive/animation/nested_simple_animation.hpp
+++ b/include/rive/animation/nested_simple_animation.hpp
@@ -5,7 +5,7 @@
 namespace rive {
     class NestedSimpleAnimation : public NestedSimpleAnimationBase {
     public:
-        void advance(float elapsedSeconds, Artboard* artboard) override;
+        void advance(float elapsedSeconds) override;
     };
 } // namespace rive
 
diff --git a/include/rive/animation/nested_state_machine.hpp b/include/rive/animation/nested_state_machine.hpp
index 04893ec..d96c07b 100644
--- a/include/rive/animation/nested_state_machine.hpp
+++ b/include/rive/animation/nested_state_machine.hpp
@@ -5,7 +5,7 @@
 namespace rive {
     class NestedStateMachine : public NestedStateMachineBase {
     public:
-        void advance(float elapsedSeconds, Artboard* artboard) override;
+        void advance(float elapsedSeconds) override;
         void initializeAnimation(Artboard* artboard) override;
     };
 } // namespace rive
diff --git a/include/rive/animation/state_instance.hpp b/include/rive/animation/state_instance.hpp
index dcdb5f2..df9f1e8 100644
--- a/include/rive/animation/state_instance.hpp
+++ b/include/rive/animation/state_instance.hpp
@@ -18,7 +18,7 @@
         StateInstance(const LayerState* layerState);
         virtual ~StateInstance();
         virtual void advance(float seconds, SMIInput** inputs) = 0;
-        virtual void apply(Artboard* artboard, float mix) = 0;
+        virtual void apply(float mix) = 0;
 
         /// Returns true when the State Machine needs to keep advancing this
         /// state.
diff --git a/include/rive/animation/system_state_instance.hpp b/include/rive/animation/system_state_instance.hpp
index 50ae376..2cc70ef 100644
--- a/include/rive/animation/system_state_instance.hpp
+++ b/include/rive/animation/system_state_instance.hpp
@@ -10,10 +10,10 @@
     /// just a no-op state (perhaps an unknown to this runtime state-type).
     class SystemStateInstance : public StateInstance {
     public:
-        SystemStateInstance(const LayerState* layerState);
+        SystemStateInstance(const LayerState* layerState, Artboard* instance);
 
         void advance(float seconds, SMIInput** inputs) override;
-        void apply(Artboard* artboard, float mix) override;
+        void apply(float mix) override;
 
         bool keepGoing() const override;
     };
diff --git a/include/rive/nested_animation.hpp b/include/rive/nested_animation.hpp
index 123ac76..bbc0a87 100644
--- a/include/rive/nested_animation.hpp
+++ b/include/rive/nested_animation.hpp
@@ -8,7 +8,7 @@
         StatusCode onAddedDirty(CoreContext* context) override;
 
         // Advance animations and apply them to the artboard.
-        virtual void advance(float elapsedSeconds, Artboard* artboard) = 0;
+        virtual void advance(float elapsedSeconds) = 0;
 
         // Initialize the animation (make instances as necessary) from the
         // source artboard.
diff --git a/skia/viewer/src/main.cpp b/skia/viewer/src/main.cpp
index 33a5593..4b4e9fd 100644
--- a/skia/viewer/src/main.cpp
+++ b/skia/viewer/src/main.cpp
@@ -92,7 +92,7 @@
     stateMachineInstance = nullptr;
 
     if (index >= 0 && index < artboard->animationCount()) {
-        animationInstance = new rive::LinearAnimationInstance(artboard->animation(index));
+        animationInstance = new rive::LinearAnimationInstance(artboard->animation(index), artboard.get());
     }
 }
 
@@ -271,7 +271,7 @@
         if (artboard != nullptr) {
             if (animationInstance != nullptr) {
                 animationInstance->advance(elapsed);
-                animationInstance->apply(artboard.get());
+                animationInstance->apply();
             } else if (stateMachineInstance != nullptr) {
                 stateMachineInstance->advance(elapsed);
             }
diff --git a/src/animation/animation_state.cpp b/src/animation/animation_state.cpp
index b6e85a8..ceb701d 100644
--- a/src/animation/animation_state.cpp
+++ b/src/animation/animation_state.cpp
@@ -7,10 +7,10 @@
 
 using namespace rive;
 
-StateInstance* AnimationState::makeInstance() const {
+StateInstance* AnimationState::makeInstance(Artboard* instance) const {
     if (animation() == nullptr) {
         // Failed to load at runtime/some new type we don't understand.
-        return new SystemStateInstance(this);
+        return new SystemStateInstance(this, instance);
     }
-    return new AnimationStateInstance(this);
+    return new AnimationStateInstance(this, instance);
 }
\ No newline at end of file
diff --git a/src/animation/animation_state_instance.cpp b/src/animation/animation_state_instance.cpp
index 9d345e6..3303d4f 100644
--- a/src/animation/animation_state_instance.cpp
+++ b/src/animation/animation_state_instance.cpp
@@ -3,15 +3,19 @@
 
 using namespace rive;
 
-AnimationStateInstance::AnimationStateInstance(const AnimationState* state) :
-    StateInstance(state), m_AnimationInstance(state->animation()), m_KeepGoing(true) {}
+AnimationStateInstance::AnimationStateInstance(const AnimationState* state,
+                                               Artboard* instance) :
+    StateInstance(state),
+    m_AnimationInstance(state->animation(), instance),
+    m_KeepGoing(true)
+{}
 
 void AnimationStateInstance::advance(float seconds, SMIInput** inputs) {
     m_KeepGoing = m_AnimationInstance.advance(seconds);
 }
 
-void AnimationStateInstance::apply(Artboard* artboard, float mix) {
-    m_AnimationInstance.apply(artboard, mix);
+void AnimationStateInstance::apply(float mix) {
+    m_AnimationInstance.apply(mix);
 }
 
 bool AnimationStateInstance::keepGoing() const { return m_KeepGoing; }
\ No newline at end of file
diff --git a/src/animation/blend_state_1d.cpp b/src/animation/blend_state_1d.cpp
index abdc1ed..778fe9b 100644
--- a/src/animation/blend_state_1d.cpp
+++ b/src/animation/blend_state_1d.cpp
@@ -6,7 +6,9 @@
 
 using namespace rive;
 
-StateInstance* BlendState1D::makeInstance() const { return new BlendState1DInstance(this); }
+StateInstance* BlendState1D::makeInstance(Artboard* instance) const {
+    return new BlendState1DInstance(this, instance);
+}
 
 StatusCode BlendState1D::import(ImportStack& importStack) {
     auto stateMachineImporter = importStack.latest<StateMachineImporter>(StateMachine::typeKey);
diff --git a/src/animation/blend_state_1d_instance.cpp b/src/animation/blend_state_1d_instance.cpp
index 439e635..4bb4408 100644
--- a/src/animation/blend_state_1d_instance.cpp
+++ b/src/animation/blend_state_1d_instance.cpp
@@ -3,8 +3,8 @@
 
 using namespace rive;
 
-BlendState1DInstance::BlendState1DInstance(const BlendState1D* blendState) :
-    BlendStateInstance<BlendState1D, BlendAnimation1D>(blendState) {}
+BlendState1DInstance::BlendState1DInstance(const BlendState1D* blendState, Artboard* instance) :
+    BlendStateInstance<BlendState1D, BlendAnimation1D>(blendState, instance) {}
 
 int BlendState1DInstance::animationIndex(float value) {
     int idx = 0;
diff --git a/src/animation/blend_state_direct.cpp b/src/animation/blend_state_direct.cpp
index dfe1f42..2879b4c 100644
--- a/src/animation/blend_state_direct.cpp
+++ b/src/animation/blend_state_direct.cpp
@@ -6,4 +6,6 @@
 
 using namespace rive;
 
-StateInstance* BlendStateDirect::makeInstance() const { return new BlendStateDirectInstance(this); }
\ No newline at end of file
+StateInstance* BlendStateDirect::makeInstance(Artboard* instance) const {
+    return new BlendStateDirectInstance(this, instance);
+}
\ No newline at end of file
diff --git a/src/animation/blend_state_direct_instance.cpp b/src/animation/blend_state_direct_instance.cpp
index 09fe7d0..77c1c2f 100644
--- a/src/animation/blend_state_direct_instance.cpp
+++ b/src/animation/blend_state_direct_instance.cpp
@@ -3,8 +3,8 @@
 
 using namespace rive;
 
-BlendStateDirectInstance::BlendStateDirectInstance(const BlendStateDirect* blendState) :
-    BlendStateInstance<BlendStateDirect, BlendAnimationDirect>(blendState) {}
+BlendStateDirectInstance::BlendStateDirectInstance(const BlendStateDirect* blendState, Artboard* instance) :
+    BlendStateInstance<BlendStateDirect, BlendAnimationDirect>(blendState, instance) {}
 
 void BlendStateDirectInstance::advance(float seconds, SMIInput** inputs) {
     BlendStateInstance<BlendStateDirect, BlendAnimationDirect>::advance(seconds, inputs);
diff --git a/src/animation/layer_state.cpp b/src/animation/layer_state.cpp
index 3cafeaf..7fce2d8 100644
--- a/src/animation/layer_state.cpp
+++ b/src/animation/layer_state.cpp
@@ -46,4 +46,6 @@
 
 void LayerState::addTransition(StateTransition* transition) { m_Transitions.push_back(transition); }
 
-StateInstance* LayerState::makeInstance() const { return new SystemStateInstance(this); }
\ No newline at end of file
+StateInstance* LayerState::makeInstance(Artboard* instance) const {
+    return new SystemStateInstance(this, instance);
+}
\ No newline at end of file
diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp
index 6ed6e72..895891c 100644
--- a/src/animation/linear_animation_instance.cpp
+++ b/src/animation/linear_animation_instance.cpp
@@ -5,8 +5,10 @@
 
 using namespace rive;
 
-LinearAnimationInstance::LinearAnimationInstance(const LinearAnimation* animation) :
+LinearAnimationInstance::LinearAnimationInstance(const LinearAnimation* animation,
+                                                 Artboard* instance) :
     m_Animation(animation),
+    m_ArtboardInstance(instance),
     m_Time(animation->enableWorkArea() ? (float)animation->workStart() / animation->fps() : 0),
     m_TotalTime(0.0f),
     m_LastTotalTime(0.0f),
diff --git a/src/animation/nested_linear_animation.cpp b/src/animation/nested_linear_animation.cpp
index 264b1af..2d418d1 100644
--- a/src/animation/nested_linear_animation.cpp
+++ b/src/animation/nested_linear_animation.cpp
@@ -7,5 +7,5 @@
 
 void NestedLinearAnimation::initializeAnimation(Artboard* artboard) {
     assert(m_AnimationInstance == nullptr);
-    m_AnimationInstance = new LinearAnimationInstance(artboard->animation(animationId()));
+    m_AnimationInstance = new LinearAnimationInstance(artboard->animation(animationId()), artboard);
 }
\ No newline at end of file
diff --git a/src/animation/nested_remap_animation.cpp b/src/animation/nested_remap_animation.cpp
index 2cba49e..fd146eb 100644
--- a/src/animation/nested_remap_animation.cpp
+++ b/src/animation/nested_remap_animation.cpp
@@ -15,8 +15,8 @@
     timeChanged();
 }
 
-void NestedRemapAnimation::advance(float elapsedSeconds, Artboard* artboard) {
+void NestedRemapAnimation::advance(float elapsedSeconds) {
     if (m_AnimationInstance != nullptr) {
-        m_AnimationInstance->apply(artboard, mix());
+        m_AnimationInstance->apply(mix());
     }
 }
\ No newline at end of file
diff --git a/src/animation/nested_simple_animation.cpp b/src/animation/nested_simple_animation.cpp
index 5f595f7..23e4ee0 100644
--- a/src/animation/nested_simple_animation.cpp
+++ b/src/animation/nested_simple_animation.cpp
@@ -3,11 +3,11 @@
 
 using namespace rive;
 
-void NestedSimpleAnimation::advance(float elapsedSeconds, Artboard* artboard) {
+void NestedSimpleAnimation::advance(float elapsedSeconds) {
     if (m_AnimationInstance != nullptr) {
         if (isPlaying()) {
             m_AnimationInstance->advance(elapsedSeconds * speed());
         }
-        m_AnimationInstance->apply(artboard, mix());
+        m_AnimationInstance->apply(mix());
     }
 }
\ No newline at end of file
diff --git a/src/animation/nested_state_machine.cpp b/src/animation/nested_state_machine.cpp
index b130ad4..2b3ad7c 100644
--- a/src/animation/nested_state_machine.cpp
+++ b/src/animation/nested_state_machine.cpp
@@ -2,6 +2,6 @@
 
 using namespace rive;
 
-void NestedStateMachine::advance(float elapsedSeconds, Artboard* artboard) {}
+void NestedStateMachine::advance(float elapsedSeconds) {}
 
 void NestedStateMachine::initializeAnimation(Artboard* artboard) {}
\ No newline at end of file
diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp
index 5a7b8c6..6ece00f 100644
--- a/src/animation/state_machine_instance.cpp
+++ b/src/animation/state_machine_instance.cpp
@@ -20,6 +20,7 @@
     private:
         static const int maxIterations = 100;
         const StateMachineLayer* m_Layer = nullptr;
+        Artboard* m_ArtboardInstance = nullptr;
 
         StateInstance* m_AnyStateInstance = nullptr;
         StateInstance* m_CurrentState = nullptr;
@@ -48,9 +49,10 @@
             delete m_StateFrom;
         }
 
-        void init(const StateMachineLayer* layer) {
+        void init(const StateMachineLayer* layer, Artboard* instance) {
+            m_ArtboardInstance = instance;
             assert(m_Layer == nullptr);
-            m_AnyStateInstance = layer->anyState()->makeInstance();
+            m_AnyStateInstance = layer->anyState()->makeInstance(instance);
             m_Layer = layer;
             changeState(m_Layer->entryState());
         }
@@ -67,7 +69,7 @@
             }
         }
 
-        bool advance(Artboard* artboard, float seconds, SMIInput** inputs, size_t inputCount) {
+        bool advance(/*Artboard* artboard, */float seconds, SMIInput** inputs, size_t inputCount) {
             m_StateChangedOnAdvance = false;
 
             if (m_CurrentState != nullptr) {
@@ -83,7 +85,7 @@
             }
 
             for (int i = 0; updateState(inputs, i != 0); i++) {
-                apply(artboard);
+                apply();
 
                 if (i == maxIterations) {
                     fprintf(stderr, "StateMachine exceeded max iterations.\n");
@@ -91,7 +93,7 @@
                 }
             }
 
-            apply(artboard);
+            apply();
 
             return m_Mix != 1.0f || m_WaitingForExit ||
                    (m_CurrentState != nullptr && m_CurrentState->keepGoing());
@@ -122,7 +124,7 @@
             if ((m_CurrentState == nullptr ? nullptr : m_CurrentState->state()) == stateTo) {
                 return false;
             }
-            m_CurrentState = stateTo == nullptr ? nullptr : stateTo->makeInstance();
+            m_CurrentState = stateTo == nullptr ? nullptr : stateTo->makeInstance(m_ArtboardInstance);
             return true;
         }
 
@@ -184,17 +186,17 @@
             return false;
         }
 
-        void apply(Artboard* artboard) {
+        void apply(/*Artboard* artboard*/) {
             if (m_HoldAnimation != nullptr) {
-                m_HoldAnimation->apply(artboard, m_HoldTime, m_MixFrom);
+                m_HoldAnimation->apply(m_ArtboardInstance, m_HoldTime, m_MixFrom);
                 m_HoldAnimation = nullptr;
             }
 
             if (m_StateFrom != nullptr && m_Mix < 1.0f) {
-                m_StateFrom->apply(artboard, m_MixFrom);
+                m_StateFrom->apply(m_MixFrom);
             }
             if (m_CurrentState != nullptr) {
-                m_CurrentState->apply(artboard, m_Mix);
+                m_CurrentState->apply(m_Mix);
             }
         }
 
@@ -246,7 +248,7 @@
     m_LayerCount = machine->layerCount();
     m_Layers = new StateMachineLayerInstance[m_LayerCount];
     for (size_t i = 0; i < m_LayerCount; i++) {
-        m_Layers[i].init(machine->layer(i));
+        m_Layers[i].init(machine->layer(i), m_ArtboardInstance);
     }
 }
 
@@ -262,7 +264,7 @@
 bool StateMachineInstance::advance(float seconds) {
     m_NeedsAdvance = false;
     for (size_t i = 0; i < m_LayerCount; i++) {
-        if (m_Layers[i].advance(m_ArtboardInstance, seconds, m_InputInstances, m_InputCount)) {
+        if (m_Layers[i].advance(seconds, m_InputInstances, m_InputCount)) {
             m_NeedsAdvance = true;
         }
     }
diff --git a/src/animation/system_state_instance.cpp b/src/animation/system_state_instance.cpp
index 3b361fd..957ac18 100644
--- a/src/animation/system_state_instance.cpp
+++ b/src/animation/system_state_instance.cpp
@@ -1,10 +1,10 @@
 #include "rive/animation/system_state_instance.hpp"
 using namespace rive;
 
-SystemStateInstance::SystemStateInstance(const LayerState* layerState) :
+SystemStateInstance::SystemStateInstance(const LayerState* layerState, Artboard* instance) :
     StateInstance(layerState) {}
 
 void SystemStateInstance::advance(float seconds, SMIInput** inputs) {}
-void SystemStateInstance::apply(Artboard* artboard, float mix) {}
+void SystemStateInstance::apply(float mix) {}
 
 bool SystemStateInstance::keepGoing() const { return false; }
\ No newline at end of file
diff --git a/src/artboard.cpp b/src/artboard.cpp
index 164c53e..85251ea 100644
--- a/src/artboard.cpp
+++ b/src/artboard.cpp
@@ -497,11 +497,13 @@
     std::vector<Core*>& cloneObjects = artboardClone->m_Objects;
     cloneObjects.push_back(artboardClone.get());
 
-    // Skip first object (artboard).
-    auto itr = m_Objects.begin();
-    while (++itr != m_Objects.end()) {
-        auto object = *itr;
-        cloneObjects.push_back(object == nullptr ? nullptr : object->clone());
+    if (!m_Objects.empty()) {
+        // Skip first object (artboard).
+        auto itr = m_Objects.begin();
+        while (++itr != m_Objects.end()) {
+            auto object = *itr;
+            cloneObjects.push_back(object == nullptr ? nullptr : object->clone());
+        }
     }
 
     for (auto animation : m_Animations) {
diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp
index f5d6253..8f86035 100644
--- a/src/nested_artboard.cpp
+++ b/src/nested_artboard.cpp
@@ -91,7 +91,7 @@
         return false;
     }
     for (auto animation : m_NestedAnimations) {
-        animation->advance(elapsedSeconds, m_NestedInstance);
+        animation->advance(elapsedSeconds);
     }
     return m_NestedInstance->advance(elapsedSeconds);
 }
diff --git a/test/linear_animation_instance_test.cpp b/test/linear_animation_instance_test.cpp
index 627b5db..f8a5b77 100644
--- a/test/linear_animation_instance_test.cpp
+++ b/test/linear_animation_instance_test.cpp
@@ -5,6 +5,11 @@
 #include <cstdio>
 
 TEST_CASE("LinearAnimationInstance oneShot", "[animation]") {
+    // For each of these tests, we cons up a dummy artboard/instance
+    // just to make the animations happy.
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -12,7 +17,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::oneShot));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
 
     // play from beginning.
     bool continuePlaying = linearAnimationInstance->advance(2.0);
@@ -33,6 +38,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance oneShot <-", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -40,7 +48,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::oneShot));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
     linearAnimationInstance->direction(-1);
     REQUIRE(linearAnimationInstance->time() == 0.0);
 
@@ -77,6 +85,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance loop ->", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -84,7 +95,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::loop));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
 
     // play from beginning.
     bool continuePlaying = linearAnimationInstance->advance(2.0);
@@ -105,6 +116,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance loop <-", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -112,7 +126,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::loop));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
     linearAnimationInstance->direction(-1);
     REQUIRE(linearAnimationInstance->time() == 0.0);
 
@@ -143,6 +157,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance loop <- work area", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 50
     linearAnimation->workStart(4);
@@ -153,7 +170,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::loop));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
     linearAnimationInstance->direction(-1);
     REQUIRE(linearAnimationInstance->time() == 2.0);
 
@@ -194,6 +211,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance pingpong ->", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -201,7 +221,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::pingPong));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
 
     // play from beginning.
     bool continuePlaying = linearAnimationInstance->advance(2.0);
@@ -223,6 +243,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance pingpong <-", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -230,7 +253,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::pingPong));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
     linearAnimationInstance->direction(-1);
     REQUIRE(linearAnimationInstance->time() == 0.0);
 
@@ -264,6 +287,9 @@
 }
 
 TEST_CASE("LinearAnimationInstance override loop", "[animation]") {
+    rive::Artboard ab;
+    auto abi = ab.instance();
+
     rive::LinearAnimation* linearAnimation = new rive::LinearAnimation();
     // duration in seconds is 5
     linearAnimation->duration(10);
@@ -271,7 +297,7 @@
     linearAnimation->loopValue(static_cast<int>(rive::Loop::oneShot));
 
     rive::LinearAnimationInstance* linearAnimationInstance =
-        new rive::LinearAnimationInstance(linearAnimation);
+        new rive::LinearAnimationInstance(linearAnimation, abi.get());
 
     // Check the loop value is same as the animation's
     REQUIRE(linearAnimationInstance->loopValue() == linearAnimation->loopValue());
@@ -284,4 +310,4 @@
 
     delete linearAnimationInstance;
     delete linearAnimation;
-}
\ No newline at end of file
+}