diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp
index 07e1c17f77..28b8bb4a9f 100644
--- a/libraries/animation/src/AnimBlendLinearMove.cpp
+++ b/libraries/animation/src/AnimBlendLinearMove.cpp
@@ -151,10 +151,10 @@ void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIn
     if (_phase < 0.0f) {
         _phase = 0.0f;
     }
-    
+
     // detect loop trigger events
     if (_phase >= 1.0f) {
-        triggersOut.setTrigger(_id + "Loop");
+        triggersOut.setTrigger(_id + "OnLoop");
         _phase = glm::fract(_phase);
     }
 
diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h
index 0f921984b1..eb9ebd33dd 100644
--- a/libraries/animation/src/AnimVariant.h
+++ b/libraries/animation/src/AnimVariant.h
@@ -209,15 +209,14 @@ public:
     void set(const QString& key, const QString& value) { _map[key] = AnimVariant(value); }
     void unset(const QString& key) { _map.erase(key); }
 
-    void setTrigger(const QString& key) { _triggers.insert(key); }
-    void clearTriggers() { _triggers.clear(); }
+    void setTrigger(const QString& key) { _map[key] = AnimVariant(true); }
 
     void setRigToGeometryTransform(const glm::mat4& rigToGeometry) {
         _rigToGeometryMat = rigToGeometry;
         _rigToGeometryRot = glmExtractRotation(rigToGeometry);
     }
 
-    void clearMap() { _map.clear(); }
+    void clearMap() { _map.clear(); _triggers.clear(); }
     bool hasKey(const QString& key) const { return _map.find(key) != _map.end(); }
 
     const AnimVariant& get(const QString& key) const {
@@ -238,7 +237,7 @@ public:
     // For stat debugging.
     std::map<QString, QString> toDebugMap() const;
 
-#ifdef NDEBUG
+#ifndef NDEBUG
     void dump() const {
         qCDebug(animation) << "AnimVariantMap =";
         for (auto& pair : _map) {
diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp
index bc4dca54f2..7842ec0804 100644
--- a/libraries/animation/src/Rig.cpp
+++ b/libraries/animation/src/Rig.cpp
@@ -1207,9 +1207,7 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons
             _networkPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
         }
         _lastAnimVars = _animVars;
-        _animVars.clearTriggers();
         _animVars = triggersOut;
-        _networkVars.clearTriggers();
         _networkVars = networkTriggersOut;
         _lastContext = context;
     }
diff --git a/tests/animation/CMakeLists.txt b/tests/animation/CMakeLists.txt
index 17999c4d8e..2af4d5f2cd 100644
--- a/tests/animation/CMakeLists.txt
+++ b/tests/animation/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Declare dependencies
 macro (setup_testcase_dependencies)
   # link in the shared libraries
-  link_hifi_libraries(shared animation gpu fbx graphics networking test-utils)
+  link_hifi_libraries(shared animation gpu fbx hfm graphics networking test-utils)
 
   package_libraries_for_deployment()
 endmacro ()
diff --git a/tests/animation/src/AnimInverseKinematicsTests.cpp b/tests/animation/src/AnimInverseKinematicsTests.cpp
index 910770bb0d..708b1b2d2a 100644
--- a/tests/animation/src/AnimInverseKinematicsTests.cpp
+++ b/tests/animation/src/AnimInverseKinematicsTests.cpp
@@ -143,7 +143,7 @@ void AnimInverseKinematicsTests::testSingleChain() {
         ikDoll.setTargetVars(QString("D"), QString("positionD"), QString("rotationD"), QString("targetTypeD"),
                              QString("weightD"), 1.0f, flexCoefficients, QString("poleVectorEnabledD"),
                              QString("poleReferenceVectorD"), QString("poleVectorD"));
-        AnimNode::Triggers triggers;
+        AnimVariantMap triggers;
 
         // the IK solution should be:
         //
@@ -236,7 +236,7 @@ void AnimInverseKinematicsTests::testSingleChain() {
         ikDoll.setTargetVars(QString("D"), QString("positionD"), QString("rotationD"), QString("targetTypeD"),
                              QString("weightD"), 1.0f, flexCoefficients, QString("poleVectorEnabledD"),
                              QString("poleReferenceVectorD"), QString("poleVectorD"));
-        AnimNode::Triggers triggers;
+        AnimVariantMap triggers;
 
         // the IK solution should be:
         //
diff --git a/tests/animation/src/AnimTests.cpp b/tests/animation/src/AnimTests.cpp
index 01c8d1c1b6..0cd9571e22 100644
--- a/tests/animation/src/AnimTests.cpp
+++ b/tests/animation/src/AnimTests.cpp
@@ -19,6 +19,7 @@
 #include <AddressManager.h>
 #include <AccountManager.h>
 #include <ResourceManager.h>
+#include <ResourceRequestObserver.h>
 #include <StatTracker.h>
 #include <test-utils/QTestExtensions.h>
 
@@ -33,6 +34,7 @@ void AnimTests::initTestCase() {
     DependencyManager::set<NodeList>(NodeType::Agent);
     DependencyManager::set<ResourceManager>();
     DependencyManager::set<AnimationCache>();
+    DependencyManager::set<ResourceRequestObserver>();
     DependencyManager::set<ResourceCacheSharedItems>();
     DependencyManager::set<StatTracker>();
 }
@@ -84,26 +86,26 @@ void AnimTests::testClipEvaulate() {
 
     AnimClip clip(id, url, startFrame, endFrame, timeScale, loopFlag, mirrorFlag);
 
-    AnimNode::Triggers triggers;
+    AnimVariantMap triggers;
     clip.evaluate(vars, context, framesToSec(10.0f), triggers);
     QCOMPARE_WITH_ABS_ERROR(clip._frame, 12.0f, TEST_EPSILON);
 
     // does it loop?
-    triggers.clear();
+    triggers.clearMap();
     clip.evaluate(vars, context, framesToSec(12.0f), triggers);
     QCOMPARE_WITH_ABS_ERROR(clip._frame, 3.0f, TEST_EPSILON);  // Note: frame 3 and not 4, because extra frame between start and end.
 
     // did we receive a loop trigger?
-    QVERIFY(std::find(triggers.begin(), triggers.end(), "myClipNodeOnLoop") != triggers.end());
+    QVERIFY(triggers.hasKey("myClipNodeOnLoop"));
 
     // does it pause at end?
-    triggers.clear();
+    triggers.clearMap();
     clip.setLoopFlagVar("FalseVar");
     clip.evaluate(vars, context, framesToSec(20.0f), triggers);
     QCOMPARE_WITH_ABS_ERROR(clip._frame, 22.0f, TEST_EPSILON);
 
     // did we receive a done trigger?
-    QVERIFY(std::find(triggers.begin(), triggers.end(), "myClipNodeOnDone") != triggers.end());
+    QVERIFY(triggers.hasKey("myClipNodeOnDone"));
 }
 
 void AnimTests::testClipEvaulateWithVars() {
@@ -133,7 +135,7 @@ void AnimTests::testClipEvaulateWithVars() {
     clip.setTimeScaleVar("timeScale2");
     clip.setLoopFlagVar("loopFlag2");
 
-    AnimNode::Triggers triggers;
+    AnimVariantMap triggers;
     clip.evaluate(vars, context, framesToSec(0.1f), triggers);
 
     // verify that the values from the AnimVariantMap made it into the clipNode's
@@ -284,11 +286,11 @@ void AnimTests::testAccumulateTime() {
     timeScale = 1.0f;
     float dt = 1.0f;
     QString id = "testNode";
-    AnimNode::Triggers triggers;
+    AnimVariantMap triggers;
     float loopFlag = true;
     float resultFrame = accumulateTime(startFrame, endFrame, timeScale, startFrame, dt, loopFlag, id, triggers);
     // a one frame looping animation should NOT trigger onLoop events
-    QVERIFY(triggers.empty());
+    QVERIFY(!triggers.hasKey("testNodeOnLoop"));
 
     const uint32_t MAX_TRIGGER_COUNT = 3;
 
@@ -296,45 +298,45 @@ void AnimTests::testAccumulateTime() {
     endFrame = 1.1f;
     timeScale = 10.0f;
     dt = 10.0f;
-    triggers.clear();
+    triggers.clearMap();
     loopFlag = true;
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, startFrame, dt, loopFlag, id, triggers);
-    // a short animation with a large dt & a large timescale, should only create a MAXIMUM of 3 loop events.
-    QVERIFY(triggers.size() <= MAX_TRIGGER_COUNT);
+    // a short animation with a large dt & a large timescale, should generate a onLoop event.
+    QVERIFY(triggers.hasKey("testNodeOnLoop"));
 }
 
 void AnimTests::testAccumulateTimeWithParameters(float startFrame, float endFrame, float timeScale) const {
 
     float dt = (1.0f / 30.0f) / timeScale;  // sec
     QString id = "testNode";
-    AnimNode::Triggers triggers;
+    AnimVariantMap triggers;
     bool loopFlag = false;
 
     float resultFrame = accumulateTime(startFrame, endFrame, timeScale, startFrame, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == startFrame + 1.0f);
-    QVERIFY(triggers.empty());
-    triggers.clear();
+    QVERIFY(!triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, resultFrame, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == startFrame + 2.0f);
-    QVERIFY(triggers.empty());
-    triggers.clear();
+    QVERIFY(!triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, resultFrame, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == startFrame + 3.0f);
-    QVERIFY(triggers.empty());
-    triggers.clear();
+    QVERIFY(!triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 
     // test onDone trigger and frame clamping.
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, endFrame - 1.0f, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == endFrame);
-    QVERIFY(!triggers.empty() && triggers[0] == "testNodeOnDone");
-    triggers.clear();
+    QVERIFY(triggers.hasKey("testNodeOnDone"));
+    triggers.clearMap();
 
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, endFrame - 0.5f, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == endFrame);
-    QVERIFY(!triggers.empty() && triggers[0] == "testNodeOnDone");
-    triggers.clear();
+    QVERIFY(triggers.hasKey("testNodeOnDone"));
+    triggers.clearMap();
 
     // test onLoop trigger and looping frame logic
     loopFlag = true;
@@ -342,26 +344,26 @@ void AnimTests::testAccumulateTimeWithParameters(float startFrame, float endFram
     // should NOT trigger loop even though we stop at last frame, because there is an extra frame between end and start frames.
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, endFrame - 1.0f, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == endFrame);
-    QVERIFY(triggers.empty());
-    triggers.clear();
+    QVERIFY(!triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 
     // now we should hit loop trigger
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, resultFrame, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == startFrame);
-    QVERIFY(!triggers.empty() && triggers[0] == "testNodeOnLoop");
-    triggers.clear();
+    QVERIFY(triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 
     // should NOT trigger loop, even though we move past the end frame, because of extra frame between end and start.
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, endFrame - 0.5f, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == endFrame + 0.5f);
-    QVERIFY(triggers.empty());
-    triggers.clear();
+    QVERIFY(!triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 
     // now we should hit loop trigger
     resultFrame = accumulateTime(startFrame, endFrame, timeScale, resultFrame, dt, loopFlag, id, triggers);
     QVERIFY(resultFrame == startFrame + 0.5f);
-    QVERIFY(!triggers.empty() && triggers[0] == "testNodeOnLoop");
-    triggers.clear();
+    QVERIFY(triggers.hasKey("testNodeOnLoop"));
+    triggers.clearMap();
 }
 
 void AnimTests::testAnimPose() {