diff --git a/engine/cmake/generated_files.cmake b/engine/cmake/generated_files.cmake
index 6644cd17f76486878a73b74112c053f759d08b2b..4582b70e4dccc0d1401de8ab06a8ffbf70ccf40d 100644
--- a/engine/cmake/generated_files.cmake
+++ b/engine/cmake/generated_files.cmake
@@ -190,6 +190,7 @@ list(APPEND ${PROJECT_NAME}_SOURCES
     src/Conversion/OscToNode/ParseStory.cpp
     src/Conversion/OscToNode/ParseStoryboard.cpp
     src/Conversion/OscToNode/ParseTrafficSignals.cpp
+    src/Node/ActNode.cpp
     src/Node/ByEntityConditionNode.cpp
     src/Node/ConditionGroupsNode.cpp
     src/Node/ConditionNode.cpp
@@ -242,6 +243,7 @@ list(APPEND ${PROJECT_NAME}_SOURCES
     src/Utils/EntityUtils.cpp
     src/Utils/EventPrioritizer.cpp
     src/Utils/Logger.cpp
+    src/Utils/StoryBoardElementStateManager.cpp
     src/Utils/TrafficSignalBuilder.cpp
 )
 
@@ -570,6 +572,7 @@ list(APPEND ${PROJECT_NAME}_HEADERS
     src/Node/PrivateNode.h
     src/Node/RepeatingSequenceNode.h
     src/Node/RootNode.h
+    src/Node/StateAwareActionNode.h
     src/Node/StoryboardNode.h
     src/Node/TrafficSignalPhaseNode.h
     src/Node/TriggerableCompositeNode.h
@@ -610,5 +613,9 @@ list(APPEND ${PROJECT_NAME}_HEADERS
     src/Utils/IControllerService.h
     src/Utils/IEventPrioritizer.h
     src/Utils/Logger.h
+    src/Utils/StoryBoardElementState.h
+    src/Utils/StoryBoardElementStateManager.h
+    src/Utils/StoryBoardElementTransition.h
+    src/Utils/StoryBoardElementType.h
     src/Utils/TrafficSignalBuilder.h
 )
diff --git a/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition.h b/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition.h
index 37d3519f392a1765eb80911cbf2d66c7b79eab3f..fcb081f7221c876e6f319310cbfd46b6405e7764 100644
--- a/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition.h
+++ b/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition.h
@@ -17,6 +17,7 @@
 #include <utility>
 
 #include "Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace OpenScenarioEngine::v1_3::Node
 {
@@ -41,12 +42,15 @@ private:
   void lookupAndRegisterData(yase::Blackboard& blackboard) final
   {
     auto environment = blackboard.get<std::shared_ptr<mantle_api::IEnvironment>>("Environment");
-
+    auto story_board_element_state_manager = blackboard.get<std::shared_ptr<StoryBoardElementStateManager>>("StoryBoardElementStateManager");
     impl_ = std::make_unique<OpenScenarioEngine::v1_3::StoryboardElementStateCondition>(
         OpenScenarioEngine::v1_3::StoryboardElementStateCondition::Values{
-            ConvertScenarioStoryboardElement(storyboardElementStateCondition_->GetStoryboardElementRef())},
+            ConvertScenarioStoryboardElementState(storyboardElementStateCondition_->GetState()),
+            ConvertScenarioStoryboardElementTransition(storyboardElementStateCondition_->GetState()),
+            ConvertScenarioStoryboardElement(storyboardElementStateCondition_->GetStoryboardElementRef()),
+            ConvertScenarioStoryboardElement(storyboardElementStateCondition_->GetStoryboardElementType())},
         OpenScenarioEngine::v1_3::StoryboardElementStateCondition::Interfaces{
-            environment});
+            environment, story_board_element_state_manager});
   }
 
   std::unique_ptr<OpenScenarioEngine::v1_3::StoryboardElementStateCondition> impl_{nullptr};
diff --git a/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.cpp b/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.cpp
index 0105b20652ca453f78a8304313ff2169797dd33c..c1098eb3c5906da04957de67495b3910c13151d9 100644
--- a/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.cpp
+++ b/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.cpp
@@ -17,11 +17,12 @@ namespace OpenScenarioEngine::v1_3
 
 bool StoryboardElementStateCondition::IsSatisfied() const
 {
-  // Note:
-  // - Access to values parse to mantle/ose datatypes: this->values.xxx
-  // - Access to mantle interfaces: this->mantle.xxx
-  Logger::Error("Method StoryboardElementStateCondition::IsSatisfied() not implemented yet (returning \"true\" by default)");
-  return true;
+  const auto& manager = mantle.story_board_element_state_manager;
+  const auto state_opt = manager->GetState(values.storyboardElementRef, values.storyboardElementType);
+  const auto transition_opt = manager->GetTransition(values.storyboardElementRef, values.storyboardElementType);
+
+  return (state_opt && *state_opt == values.state) ||
+         (transition_opt && *transition_opt == values.transition);
 }
 
 }  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.h b/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.h
index 9c5d42434428a5778274e719a16f8d4688026844..6f75ab1557fdab50aed5e3d30693146e27d49d4b 100644
--- a/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.h
+++ b/engine/gen/Storyboard/ByValueCondition/StoryboardElementStateCondition_impl.h
@@ -13,6 +13,7 @@
 #include <MantleAPI/Execution/i_environment.h>
 
 #include "Conversion/OscToMantle/ConvertScenarioStoryboardElement.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace OpenScenarioEngine::v1_3
 {
@@ -22,11 +23,15 @@ class StoryboardElementStateCondition
 public:
   struct Values
   {
+    StoryBoardElementState state;
+    StoryBoardElementTransition transition;
     StoryboardElement storyboardElementRef;
+    StoryBoardElementType storyboardElementType;
   };
   struct Interfaces
   {
     std::shared_ptr<mantle_api::IEnvironment> environment;
+    std::shared_ptr<StoryBoardElementStateManager> story_board_element_state_manager;
   };
 
   StoryboardElementStateCondition(Values values, Interfaces interfaces)
@@ -40,4 +45,4 @@ private:
   Interfaces mantle;
 };
 
-}  // namespace OpenScenarioEngine::v1_3
\ No newline at end of file
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/gen/Storyboard/MotionControlAction/SpeedAction.h b/engine/gen/Storyboard/MotionControlAction/SpeedAction.h
index b866ac69ac2213a115e916850d2894b2cc766d93..95a9f4c1cb11d020003d88f443d3faaaabe295c3 100644
--- a/engine/gen/Storyboard/MotionControlAction/SpeedAction.h
+++ b/engine/gen/Storyboard/MotionControlAction/SpeedAction.h
@@ -1,5 +1,6 @@
 /********************************************************************************
  * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *               2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -16,33 +17,33 @@
 #include <cassert>
 #include <utility>
 
+#include "Node/StateAwareActionNode.h"
 #include "Storyboard/MotionControlAction/MotionControlAction.h"
 #include "Storyboard/MotionControlAction/SpeedAction_impl.h"
 #include "Utils/EntityBroker.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace OpenScenarioEngine::v1_3::Node
 {
-class SpeedAction : public yase::ActionNode
+class SpeedAction : public StateAwareActionNode
 {
 public:
-  SpeedAction(std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ISpeedAction> speedAction)
-      : yase::ActionNode{"SpeedAction"},
-        speedAction_{speedAction}
+  explicit SpeedAction(std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ISpeedAction> speedAction)
+      : StateAwareActionNode("SpeedAction", [this]()
+                             {
+          assert(impl_);
+          return impl_->Step(); }),
+        speedAction_{std::move(speedAction)}
   {
   }
 
   void onInit() override{};
 
 private:
-  yase::NodeStatus tick() override
+  void lookupAndRegisterData(yase::Blackboard& blackboard) override
   {
-    assert(impl_);
-    const auto is_finished = impl_->Step();
-    return is_finished ? yase::NodeStatus::kSuccess : yase::NodeStatus::kRunning;
-  };
+    StateAwareActionNode::lookupAndRegisterData(blackboard);
 
-  void lookupAndRegisterData(yase::Blackboard& blackboard) final
-  {
     auto environment = blackboard.get<std::shared_ptr<mantle_api::IEnvironment>>("Environment");
     const auto entityBroker = blackboard.get<EntityBroker::Ptr>("EntityBroker");
 
@@ -51,12 +52,14 @@ private:
             entityBroker->GetEntities(),
             ConvertScenarioTransitionDynamics(speedAction_->GetSpeedActionDynamics()),
             [=]()
-            { return ConvertScenarioSpeedActionTarget(environment, speedAction_->GetSpeedActionTarget()); }},
+            {
+              return ConvertScenarioSpeedActionTarget(environment, speedAction_->GetSpeedActionTarget());
+            }},
         OpenScenarioEngine::v1_3::SpeedAction::Interfaces{
             environment});
   }
 
-  std::unique_ptr<OpenScenarioEngine::v1_3::MotionControlAction<OpenScenarioEngine::v1_3::SpeedAction>> impl_{nullptr};
+  std::unique_ptr<OpenScenarioEngine::v1_3::MotionControlAction<OpenScenarioEngine::v1_3::SpeedAction>> impl_;
   std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ISpeedAction> speedAction_;
 };
 
diff --git a/engine/src/Conversion/OscToMantle/ConvertScenarioStoryboardElement.h b/engine/src/Conversion/OscToMantle/ConvertScenarioStoryboardElement.h
index bb965a11fea4667da84215396925574636ffc8ca..7925025379d4ca17130a656d330ccd089fb4926b 100644
--- a/engine/src/Conversion/OscToMantle/ConvertScenarioStoryboardElement.h
+++ b/engine/src/Conversion/OscToMantle/ConvertScenarioStoryboardElement.h
@@ -16,8 +16,13 @@
 #include <memory>
 #include <string>
 
+#include "Utils/StoryBoardElementState.h"
+#include "Utils/StoryBoardElementTransition.h"
+#include "Utils/StoryBoardElementType.h"
+
 namespace OpenScenarioEngine::v1_3
 {
+
 using StoryboardElement = std::string;
 
 inline StoryboardElement ConvertScenarioStoryboardElement(const std::shared_ptr<NET_ASAM_OPENSCENARIO::INamedReference<NET_ASAM_OPENSCENARIO::v1_3::IStoryboardElement>>& storyboardElement)
@@ -25,9 +30,83 @@ inline StoryboardElement ConvertScenarioStoryboardElement(const std::shared_ptr<
   return storyboardElement->GetNameRef();
 }
 
-inline StoryboardElement ConvertScenarioStoryboardElement(const std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::IStoryboardElement>& /*storyboardElement*/)
+inline StoryBoardElementType ConvertScenarioStoryboardElement(
+    const NET_ASAM_OPENSCENARIO::v1_3::StoryboardElementType& type)
+{
+  using SourceType = NET_ASAM_OPENSCENARIO::v1_3::StoryboardElementType::StoryboardElementTypeEnum;
+
+  if (type == SourceType::ACT)
+  {
+    return StoryBoardElementType::kAct;
+  }
+  if (type == SourceType::ACTION)
+  {
+    return StoryBoardElementType::kAction;
+  }
+  if (type == SourceType::EVENT)
+  {
+    return StoryBoardElementType::kEvent;
+  }
+  if (type == SourceType::MANEUVER)
+  {
+    return StoryBoardElementType::kManeuver;
+  }
+  if (type == SourceType::MANEUVER_GROUP)
+  {
+    return StoryBoardElementType::kManeuverGroup;
+  }
+  if (type == SourceType::STORY)
+  {
+    return StoryBoardElementType::kStory;
+  }
+
+  throw std::runtime_error("ConvertScenarioStoryBoardElement: Unsupported Element Type");
+}
+
+inline StoryBoardElementState ConvertScenarioStoryboardElementState(
+    const NET_ASAM_OPENSCENARIO::v1_3::StoryboardElementState& state)
 {
-  return {};
+  using SourceState = NET_ASAM_OPENSCENARIO::v1_3::StoryboardElementState::StoryboardElementStateEnum;
+
+  if (state == SourceState::COMPLETE_STATE)
+  {
+    return StoryBoardElementState::kCompleteState;
+  }
+  if (state == SourceState::RUNNING_STATE)
+  {
+    return StoryBoardElementState::kRunningState;
+  }
+  if (state == SourceState::STANDBY_STATE)
+  {
+    return StoryBoardElementState::kStandbyState;
+  }
+
+  return StoryBoardElementState::kUnknown;
+}
+
+inline StoryBoardElementTransition ConvertScenarioStoryboardElementTransition(
+    const NET_ASAM_OPENSCENARIO::v1_3::StoryboardElementState& state)
+{
+  using SourceState = NET_ASAM_OPENSCENARIO::v1_3::StoryboardElementState::StoryboardElementStateEnum;
+
+  if (state == SourceState::END_TRANSITION)
+  {
+    return StoryBoardElementTransition::kEndTransition;
+  }
+  if (state == SourceState::SKIP_TRANSITION)
+  {
+    return StoryBoardElementTransition::kSkipTransition;
+  }
+  if (state == SourceState::START_TRANSITION)
+  {
+    return StoryBoardElementTransition::kStartTransition;
+  }
+  if (state == SourceState::STOP_TRANSITION)
+  {
+    return StoryBoardElementTransition::kStopTransition;
+  }
+
+  return StoryBoardElementTransition::kUnknown;
 }
 
-}  // namespace OpenScenarioEngine::v1_3
\ No newline at end of file
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/src/Node/ActNode.cpp b/engine/src/Node/ActNode.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b33e9cef1c4a557ad2093e21ce6201c4e936ff8
--- /dev/null
+++ b/engine/src/Node/ActNode.cpp
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#include "Node/ActNode.h"
+
+namespace OpenScenarioEngine::v1_3::Node
+{
+
+ActNode::ActNode(const std::string& name,
+                 yase::BehaviorNode::Ptr maneuver_groups,
+                 yase::BehaviorNode::Ptr start_trigger,
+                 yase::BehaviorNode::Ptr stop_trigger)
+    : TriggerableCompositeNode{name}, start_trigger_(start_trigger), stop_trigger_(stop_trigger)
+{
+  set(std::move(maneuver_groups), StopTriggerPtr{std::move(stop_trigger)}, StartTriggerPtr{std::move(start_trigger)});
+}
+
+void ActNode::lookupAndRegisterData(yase::Blackboard& blackboard)
+{
+  story_board_element_state_manager_ = blackboard.get<std::shared_ptr<OpenScenarioEngine::v1_3::StoryBoardElementStateManager>>("StoryBoardElementStateManager");
+  story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementState::kStandbyState);
+}
+
+yase::NodeStatus ActNode::tick()
+{
+  // reset transition to unknown in every tick
+  story_board_element_state_manager_->ResetTransition(getOriginalName(), StoryBoardElementType::kAct);
+
+  auto current_status = TriggerableCompositeNode::tick();
+
+  if (start_trigger_ == nullptr || start_trigger_->status() == yase::NodeStatus::kSuccess)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementTransition::kStartTransition);
+  }
+  if (stop_trigger_ != nullptr && stop_trigger_->status() == yase::NodeStatus::kSuccess)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementTransition::kStopTransition);
+  }
+
+  if (current_status == yase::NodeStatus::kSuccess)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementTransition::kEndTransition);
+    // Since maximumExecutionCount is not supported, after status is kSuccess, the state will be updated to kCompleteState rather that kStandbyState.
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementState::kCompleteState);
+  }
+  else if (current_status == yase::NodeStatus::kRunning)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementState::kRunningState);
+  }
+  else
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementTransition::kUnknown);
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kAct, StoryBoardElementState::kUnknown);
+  }
+
+  return current_status;
+}
+
+}  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Node/ActNode.h b/engine/src/Node/ActNode.h
index 7ec0683a31c853c0a8171c9aca05c5ee8eff90bc..ac8c7ddaf4e8c7f51de2214f071070bd632bb88c 100644
--- a/engine/src/Node/ActNode.h
+++ b/engine/src/Node/ActNode.h
@@ -1,6 +1,7 @@
 /********************************************************************************
  * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
  *               2021 Max Paul Bauer - Robert Bosch GmbH
+ *               2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -14,6 +15,7 @@
 #include <utility>
 
 #include "Node/TriggerableCompositeNode.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace OpenScenarioEngine::v1_3::Node
 {
@@ -23,11 +25,16 @@ public:
   ActNode(const std::string& name,
           yase::BehaviorNode::Ptr maneuver_groups,
           yase::BehaviorNode::Ptr start_trigger = nullptr,
-          yase::BehaviorNode::Ptr stop_trigger = nullptr)
-      : TriggerableCompositeNode{name}
-  {
-    set(std::move(maneuver_groups), StopTriggerPtr{std::move(stop_trigger)}, StartTriggerPtr{std::move(start_trigger)});
-  }
+          yase::BehaviorNode::Ptr stop_trigger = nullptr);
+
+  void lookupAndRegisterData(yase::Blackboard& blackboard) override;
+
+  yase::NodeStatus tick() override;
+
+private:
+  yase::BehaviorNode::Ptr start_trigger_;
+  yase::BehaviorNode::Ptr stop_trigger_;
+  std::shared_ptr<StoryBoardElementStateManager> story_board_element_state_manager_;
 };
 
-}  // namespace OpenScenarioEngine::v1_3::Node
\ No newline at end of file
+}  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Node/EventNode.cpp b/engine/src/Node/EventNode.cpp
index 532f5765a23e6713115eded5fd38c5910cc64ccf..e14e52291468afdba81750ec4b15e492b437e6b0 100644
--- a/engine/src/Node/EventNode.cpp
+++ b/engine/src/Node/EventNode.cpp
@@ -25,14 +25,28 @@ EventNode::EventNode(const std::string& name,
 
 void EventNode::lookupAndRegisterData(yase::Blackboard& blackboard)
 {
-  event_prioritizer_ = blackboard.get<std::shared_ptr<OpenScenarioEngine::v1_3::IEventPrioritizer> >("EventPrioritizer");
+  event_prioritizer_ = blackboard.get<std::shared_ptr<OpenScenarioEngine::v1_3::IEventPrioritizer>>("EventPrioritizer");
   event_prioritizer_->RegisterEvent(name(), event_priority_);
+  story_board_element_state_manager_ = blackboard.get<std::shared_ptr<OpenScenarioEngine::v1_3::StoryBoardElementStateManager>>("StoryBoardElementStateManager");
+  story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementState::kStandbyState);
 }
 
 yase::NodeStatus EventNode::tick()
 {
-  if (event_prioritizer_->ShouldStopChild(name()) || event_prioritizer_->ShouldSkipChild(name()))
+  // reset transition to unknown in every tick
+  story_board_element_state_manager_->ResetTransition(getOriginalName(), StoryBoardElementType::kEvent);
+
+  if (event_prioritizer_->ShouldStopChild(name()))
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementTransition::kStopTransition);
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementState::kCompleteState);
+    return yase::NodeStatus::kSuccess;
+  }
+
+  if (event_prioritizer_->ShouldSkipChild(name()))
   {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementTransition::kSkipTransition);
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementState::kStandbyState);
     return yase::NodeStatus::kSuccess;
   }
 
@@ -40,9 +54,26 @@ yase::NodeStatus EventNode::tick()
 
   if (start_trigger_ == nullptr || start_trigger_->status() == yase::NodeStatus::kSuccess)
   {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementTransition::kStartTransition);
     event_prioritizer_->EventStarted(name());
   }
 
+  if (current_status == yase::NodeStatus::kSuccess)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementTransition::kEndTransition);
+    // Since maximumExecutionCount is not supported, after status is kSuccess, the state will be updated to kCompleteState rather that kStandbyState.
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementState::kCompleteState);
+  }
+  else if (current_status == yase::NodeStatus::kRunning)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementState::kRunningState);
+  }
+  else
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementTransition::kUnknown);
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kEvent, StoryBoardElementState::kUnknown);
+  }
+
   return current_status;
 }
 
diff --git a/engine/src/Node/EventNode.h b/engine/src/Node/EventNode.h
index 2ea9f955bb194b9385ad3214e52370702fd631f7..4aac076cacabfa0405ec29513274ba55cf04f536 100644
--- a/engine/src/Node/EventNode.h
+++ b/engine/src/Node/EventNode.h
@@ -15,6 +15,7 @@
 #include "Node/TriggerableCompositeNode.h"
 #include "Utils/EventPriority.h"
 #include "Utils/IEventPrioritizer.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace OpenScenarioEngine::v1_3::Node
 {
@@ -42,6 +43,7 @@ private:
   EventPriority event_priority_;
   yase::BehaviorNode::Ptr start_trigger_;
   std::shared_ptr<IEventPrioritizer> event_prioritizer_;
+  std::shared_ptr<StoryBoardElementStateManager> story_board_element_state_manager_;
 };
 
 }  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Node/ManeuverNode.cpp b/engine/src/Node/ManeuverNode.cpp
index 30f70cb523c3f555714301d9b32f16226056438b..0398e046ebc5170742d9f59d4d37d027afc0629f 100644
--- a/engine/src/Node/ManeuverNode.cpp
+++ b/engine/src/Node/ManeuverNode.cpp
@@ -15,19 +15,44 @@
 namespace OpenScenarioEngine::v1_3::Node
 {
 ManeuverNode::ManeuverNode(const std::string& name)
-    : yase::DecoratorNode{name}, eventPrioritizer_{std::make_shared<EventPrioritizer>()}
+    : yase::DecoratorNode{name}, eventPrioritizer_{std::make_shared<EventPrioritizer>()}, original_name_(name)
 {
 }
 
+const std::string& ManeuverNode::getOriginalName() const
+{
+  return original_name_;
+}
+
 yase::NodeStatus ManeuverNode::tick()
 {
   eventPrioritizer_->UpdateOverriddenEvents();
-  return child().executeTick();
+
+  auto current_status = child().executeTick();
+
+  if (current_status == yase::NodeStatus::kSuccess)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kManeuver, StoryBoardElementTransition::kEndTransition);
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kManeuver, StoryBoardElementState::kCompleteState);
+  }
+  else if (current_status == yase::NodeStatus::kRunning)
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kManeuver, StoryBoardElementState::kRunningState);
+  }
+  else
+  {
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kManeuver, StoryBoardElementTransition::kUnknown);
+    story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kManeuver, StoryBoardElementState::kUnknown);
+  }
+
+  return current_status;
 }
 
-void ManeuverNode::lookupAndRegisterData(yase::Blackboard &blackboard)
+void ManeuverNode::lookupAndRegisterData(yase::Blackboard& blackboard)
 {
   blackboard.set("EventPrioritizer", eventPrioritizer_);
+  story_board_element_state_manager_ = blackboard.get<std::shared_ptr<OpenScenarioEngine::v1_3::StoryBoardElementStateManager>>("StoryBoardElementStateManager");
+  story_board_element_state_manager_->Update(getOriginalName(), StoryBoardElementType::kManeuverGroup, StoryBoardElementState::kStandbyState);
 }
 
 }  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Node/ManeuverNode.h b/engine/src/Node/ManeuverNode.h
index 9fbadfab283e5580f06a6742eebcf8d3924c99e2..0e6855a8a5091327e130cd5ad30eb645e02b1d69 100644
--- a/engine/src/Node/ManeuverNode.h
+++ b/engine/src/Node/ManeuverNode.h
@@ -12,6 +12,8 @@
 
 #include <agnostic_behavior_tree/decorator_node.h>
 
+#include "Utils/StoryBoardElementStateManager.h"
+
 namespace OpenScenarioEngine::v1_3
 {
 class IEventPrioritizer;
@@ -28,11 +30,15 @@ public:
   /// @param name Name of the maneuver node
   explicit ManeuverNode(const std::string& name);
 
+  [[nodiscard]] const std::string& getOriginalName() const;
+
 private:
   void lookupAndRegisterData(yase::Blackboard& blackboard) override;
   yase::NodeStatus tick() final;
 
   std::shared_ptr<IEventPrioritizer> eventPrioritizer_;
+  std::shared_ptr<StoryBoardElementStateManager> story_board_element_state_manager_;
+  std::string original_name_;
 };
 
 }  // namespace Node
diff --git a/engine/src/Node/RootNode.cpp b/engine/src/Node/RootNode.cpp
index ae0a474b6eaae26360dcc10ddb1ef71723956bd8..fc22221fc45158555919455bb7efe5dfffa43e94 100644
--- a/engine/src/Node/RootNode.cpp
+++ b/engine/src/Node/RootNode.cpp
@@ -1,5 +1,6 @@
 /********************************************************************************
  * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *               2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -25,7 +26,8 @@ RootNode::RootNode(std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::IScenarioDefinit
       environment_{environment},
       controller_service_{controller_service},
       stochastics_{stochastics},
-      engine_abort_flags_{engine_abort_flags}
+      engine_abort_flags_{engine_abort_flags},
+      story_board_element_state_manager_{std::make_shared<StoryBoardElementStateManager>()}
 {
   if (auto storyboard = scenarioDefinition->GetStoryboard(); storyboard)
   {
@@ -44,6 +46,7 @@ void RootNode::lookupAndRegisterData(yase::Blackboard& blackboard)
   blackboard.set("ControllerService", controller_service_);
   blackboard.set("Stochastics", stochastics_);
   blackboard.set("EngineAbortFlags", engine_abort_flags_);
+  blackboard.set("StoryBoardElementStateManager", story_board_element_state_manager_);
 }
 
 }  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Node/RootNode.h b/engine/src/Node/RootNode.h
index 9b4b7e65888ddb63c1dc31f2aae1a1a64267cbb5..91e76da3c32b7d969b40007e8cc2089f0c687aa1 100644
--- a/engine/src/Node/RootNode.h
+++ b/engine/src/Node/RootNode.h
@@ -1,5 +1,6 @@
 /********************************************************************************
  * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *               2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -15,9 +16,9 @@
 
 #include <memory>
 
-#include "Utils/EngineAbortFlags.h"
 #include "Stochastics/StochasticsInterface.h"
-
+#include "Utils/EngineAbortFlags.h"
+#include "Utils/StoryBoardElementStateManager.h"
 namespace OpenScenarioEngine::v1_3
 {
 
@@ -45,8 +46,9 @@ private:
   std::shared_ptr<IControllerService> controller_service_;
   std::shared_ptr<StochasticsInterface> stochastics_;
   std::shared_ptr<EngineAbortFlags> engine_abort_flags_;
+  std::shared_ptr<StoryBoardElementStateManager> story_board_element_state_manager_;
 };
 
 }  // namespace Node
 
-}  // namespace OpenScenarioEngine::v1_3
\ No newline at end of file
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/src/Node/StateAwareActionNode.h b/engine/src/Node/StateAwareActionNode.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c2834f1cac42dfb2bdea215795709441e504e3b
--- /dev/null
+++ b/engine/src/Node/StateAwareActionNode.h
@@ -0,0 +1,56 @@
+/********************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#pragma once
+
+#include <agnostic_behavior_tree/action_node.h>
+
+#include "Utils/StoryBoardElementStateManager.h"
+
+namespace OpenScenarioEngine::v1_3::Node
+{
+
+using ImplStepFunction = std::function<bool()>;
+
+class StateAwareActionNode : public yase::ActionNode
+{
+public:
+  StateAwareActionNode(const std::string& name, ImplStepFunction step_fn)
+      : yase::ActionNode{name}, step_fn_{std::move(step_fn)} {}
+
+  yase::NodeStatus tick() override
+  {
+    const bool is_finished = step_fn_();
+
+    if (is_finished)
+    {
+      state_manager_->Update(name(), type_, StoryBoardElementTransition::kEndTransition);
+      state_manager_->Update(name(), type_, StoryBoardElementState::kCompleteState);
+      return yase::NodeStatus::kSuccess;
+    }
+
+    state_manager_->Update(name(), type_, StoryBoardElementState::kRunningState);
+    return yase::NodeStatus::kRunning;
+  }
+
+  void lookupAndRegisterData(yase::Blackboard& blackboard) override
+  {
+    state_manager_ = blackboard.get<std::shared_ptr<StoryBoardElementStateManager>>("StoryBoardElementStateManager");
+    state_manager_->Update(name(), type_, StoryBoardElementState::kStandbyState);
+  }
+
+protected:
+  StoryBoardElementType type_{StoryBoardElementType::kAction};
+
+private:
+  ImplStepFunction step_fn_;
+  std::shared_ptr<StoryBoardElementStateManager> state_manager_;
+};
+}  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Node/TriggerableCompositeNode.h b/engine/src/Node/TriggerableCompositeNode.h
index 5f932de2b5a43f3a8bc14efa981141e7001deefb..e4c1c11234325ef193eb4b2e536151aec9e3bc3f 100644
--- a/engine/src/Node/TriggerableCompositeNode.h
+++ b/engine/src/Node/TriggerableCompositeNode.h
@@ -1,6 +1,7 @@
 /********************************************************************************
  * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
  *               2021 Max Paul Bauer - Robert Bosch GmbH
+ *               2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -111,7 +112,7 @@ class TriggerableCompositeNode : public yase::CompositeNode
 {
 public:
   explicit TriggerableCompositeNode(const std::string& name)
-      : CompositeNode{name} {};
+      : CompositeNode{name}, original_name_(name){};
   ~TriggerableCompositeNode() override = default;
 
   void onInit() override
@@ -150,6 +151,8 @@ public:
     }
   }
 
+  [[nodiscard]] const std::string& getOriginalName() const { return original_name_; }
+
 protected:
   using yase::CompositeNode::addChild;
 
@@ -265,6 +268,7 @@ private:
   TransientNode::Ptr m_child_node{nullptr};
   TransientNode::Ptr stop_trigger_node_{nullptr};
   yase::NodeStatus stop_trigger_status_{yase::NodeStatus::kIdle};
+  std::string original_name_;
 };
 
-}  // namespace OpenScenarioEngine::v1_3::Node
\ No newline at end of file
+}  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Storyboard/MotionControlAction/LongitudinalDistanceAction.h b/engine/src/Storyboard/MotionControlAction/LongitudinalDistanceAction.h
index 67f7bcf1be1f97a3b0567f7f87f46368abf4c592..0adcd69c735cae57e568e35f068c44eeeb09121e 100644
--- a/engine/src/Storyboard/MotionControlAction/LongitudinalDistanceAction.h
+++ b/engine/src/Storyboard/MotionControlAction/LongitudinalDistanceAction.h
@@ -1,5 +1,6 @@
 /********************************************************************************
  * Copyright (c) 2021-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+ *               2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -16,17 +17,22 @@
 #include <cassert>
 #include <utility>
 
+#include "Node/StateAwareActionNode.h"
 #include "Storyboard/MotionControlAction/LongitudinalDistanceAction_impl.h"
 #include "Storyboard/MotionControlAction/MotionControlAction.h"
 #include "Utils/EntityBroker.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace OpenScenarioEngine::v1_3::Node
 {
-class LongitudinalDistanceAction : public yase::ActionNode
+class LongitudinalDistanceAction : public StateAwareActionNode
 {
 public:
   explicit LongitudinalDistanceAction(std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ILongitudinalDistanceAction> longitudinalDistanceAction)
-      : yase::ActionNode{"LongitudinalDistanceAction"},
+      : StateAwareActionNode("LongitudinalDistanceAction", [this]()
+                             {
+          assert(impl_);
+          return impl_->Step(); }),
         longitudinalDistanceAction_{std::move(longitudinalDistanceAction)}
   {
   }
@@ -34,15 +40,10 @@ public:
   void onInit() override{};
 
 private:
-  yase::NodeStatus tick() override
+  void lookupAndRegisterData(yase::Blackboard& blackboard) override
   {
-    assert(impl_);
-    const auto is_finished = impl_->Step();
-    return is_finished ? yase::NodeStatus::kSuccess : yase::NodeStatus::kRunning;
-  };
+    StateAwareActionNode::lookupAndRegisterData(blackboard);
 
-  void lookupAndRegisterData(yase::Blackboard& blackboard) final
-  {
     auto environment = blackboard.get<std::shared_ptr<mantle_api::IEnvironment>>("Environment");
     const auto entityBroker = blackboard.get<EntityBroker::Ptr>("EntityBroker");
 
@@ -51,7 +52,8 @@ private:
             entityBroker->GetEntities(),
             longitudinalDistanceAction_->GetContinuous(),
             longitudinalDistanceAction_->GetFreespace(),
-            [=]() {
+            [=]()
+            {
               return ConvertScenarioLongitudinalDistance(
                   environment,
                   longitudinalDistanceAction_->IsSetDistance(),
@@ -64,12 +66,11 @@ private:
             ConvertScenarioDynamicConstraints(longitudinalDistanceAction_->IsSetDynamicConstraints(), longitudinalDistanceAction_->GetDynamicConstraints()),
             ConvertScenarioEntity(longitudinalDistanceAction_->GetEntityRef()),
             ConvertScenarioCoordinateSystem(longitudinalDistanceAction_->GetCoordinateSystem())},
-        OpenScenarioEngine::v1_3::LongitudinalDistanceAction::Interfaces{
-            environment});
+        OpenScenarioEngine::v1_3::LongitudinalDistanceAction::Interfaces{environment});
   }
 
-  std::unique_ptr<OpenScenarioEngine::v1_3::MotionControlAction<OpenScenarioEngine::v1_3::LongitudinalDistanceAction>> impl_{nullptr};
+  std::unique_ptr<OpenScenarioEngine::v1_3::MotionControlAction<OpenScenarioEngine::v1_3::LongitudinalDistanceAction>> impl_;
   std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::ILongitudinalDistanceAction> longitudinalDistanceAction_;
 };
 
-}  // namespace OpenScenarioEngine::v1_3::Node
\ No newline at end of file
+}  // namespace OpenScenarioEngine::v1_3::Node
diff --git a/engine/src/Utils/StoryBoardElementState.h b/engine/src/Utils/StoryBoardElementState.h
new file mode 100644
index 0000000000000000000000000000000000000000..b76edea6b278682a0172c5ea4bd5993e849ee896
--- /dev/null
+++ b/engine/src/Utils/StoryBoardElementState.h
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#pragma once
+#include <cstdint>
+
+namespace OpenScenarioEngine::v1_3
+{
+/// Definition of StoryBoardElementState
+///
+/// \see https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/StoryboardElementState.html
+enum class StoryBoardElementState : std::uint8_t
+{
+  kCompleteState,
+  kRunningState,
+  kStandbyState,
+  kUnknown
+};
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/src/Utils/StoryBoardElementStateManager.cpp b/engine/src/Utils/StoryBoardElementStateManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..815b6b4b1e603c3ea0eb9086e912ed3e5c29610d
--- /dev/null
+++ b/engine/src/Utils/StoryBoardElementStateManager.cpp
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#include "Utils/StoryBoardElementStateManager.h"
+
+namespace OpenScenarioEngine::v1_3
+{
+
+void StoryBoardElementStateManager::Update(const StoryBoardElement& name, StoryBoardElementType type, StoryBoardElementState state)
+{
+  std::lock_guard<std::mutex> lock(mutex_);
+  states_[{name, type}] = state;
+}
+
+void StoryBoardElementStateManager::Update(const StoryBoardElement& name, StoryBoardElementType type, StoryBoardElementTransition transition)
+{
+  std::lock_guard<std::mutex> lock(mutex_);
+  transitions_[{name, type}] = transition;
+}
+
+void StoryBoardElementStateManager::ResetState(const StoryBoardElement& name, StoryBoardElementType type)
+{
+  std::lock_guard<std::mutex> lock(mutex_);
+  states_[{name, type}] = StoryBoardElementState::kUnknown;
+}
+
+void StoryBoardElementStateManager::ResetTransition(const StoryBoardElement& name, StoryBoardElementType type)
+{
+  std::lock_guard<std::mutex> lock(mutex_);
+  transitions_[{name, type}] = StoryBoardElementTransition::kUnknown;
+}
+
+std::optional<StoryBoardElementState> StoryBoardElementStateManager::GetState(const StoryBoardElement& name, StoryBoardElementType type) const
+{
+  std::lock_guard<std::mutex> lock(mutex_);
+
+  StoryBoardElementKey key{name, type};
+  auto it = states_.find(key);
+  if (it != states_.end())
+  {
+    return it->second;
+  }
+  return std::nullopt;
+}
+
+std::optional<StoryBoardElementTransition> StoryBoardElementStateManager::GetTransition(const StoryBoardElement& name, StoryBoardElementType type) const
+{
+  std::lock_guard<std::mutex> lock(mutex_);
+
+  StoryBoardElementKey key{name, type};
+  auto it = transitions_.find(key);
+  if (it != transitions_.end())
+  {
+    return it->second;
+  }
+  return std::nullopt;
+}
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/src/Utils/StoryBoardElementStateManager.h b/engine/src/Utils/StoryBoardElementStateManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..e945d1aeced177afb7beaf54d77e15547180da21
--- /dev/null
+++ b/engine/src/Utils/StoryBoardElementStateManager.h
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#pragma once
+
+#include <openScenarioLib/generated/v1_3/api/EnumerationsV1_3.h>
+
+#include <mutex>
+#include <optional>
+#include <unordered_map>
+
+#include "Utils/StoryBoardElementState.h"
+#include "Utils/StoryBoardElementTransition.h"
+#include "Utils/StoryBoardElementType.h"
+
+namespace OpenScenarioEngine::v1_3
+{
+
+using StoryBoardElement = std::string;
+
+struct StoryBoardElementKey
+{
+  StoryBoardElement name;
+  StoryBoardElementType type;
+
+  bool operator==(const StoryBoardElementKey& other) const
+  {
+    return name == other.name && type == other.type;
+  }
+};
+
+struct StoryBoardElementKeyHasher
+{
+  std::size_t operator()(const StoryBoardElementKey& key) const
+  {
+    std::size_t h1 = std::hash<std::string>{}(key.name);
+    std::size_t h2 = std::hash<std::underlying_type_t<StoryBoardElementType>>{}(static_cast<std::underlying_type_t<StoryBoardElementType>>(key.type));
+    return h1 ^ (h2 << 1);
+  }
+};
+
+class StoryBoardElementStateManager
+{
+public:
+  void Update(const StoryBoardElement& name, StoryBoardElementType type, StoryBoardElementState state);
+  void Update(const StoryBoardElement& name, StoryBoardElementType type, StoryBoardElementTransition transition);
+  void ResetState(const StoryBoardElement& name, StoryBoardElementType type);
+  void ResetTransition(const StoryBoardElement& name, StoryBoardElementType type);
+  [[nodiscard]] std::optional<StoryBoardElementState> GetState(const StoryBoardElement& name, StoryBoardElementType type) const;
+  [[nodiscard]] std::optional<StoryBoardElementTransition> GetTransition(const StoryBoardElement& name, StoryBoardElementType type) const;
+
+private:
+  mutable std::mutex mutex_;
+  std::unordered_map<StoryBoardElementKey, StoryBoardElementState, StoryBoardElementKeyHasher> states_;
+  std::unordered_map<StoryBoardElementKey, StoryBoardElementTransition, StoryBoardElementKeyHasher> transitions_;
+};
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/src/Utils/StoryBoardElementTransition.h b/engine/src/Utils/StoryBoardElementTransition.h
new file mode 100644
index 0000000000000000000000000000000000000000..998203b5ababc0f8fe5f89a5fd5efabeca72a580
--- /dev/null
+++ b/engine/src/Utils/StoryBoardElementTransition.h
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#pragma once
+#include <cstdint>
+
+namespace OpenScenarioEngine::v1_3
+{
+/// Definition of StoryBoardElementTransition
+///
+/// \see https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/StoryboardElementState.html
+enum class StoryBoardElementTransition : std::uint8_t
+{
+  kEndTransition,
+  kSkipTransition,
+  kStartTransition,
+  kStopTransition,
+  kUnknown
+};
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/src/Utils/StoryBoardElementType.h b/engine/src/Utils/StoryBoardElementType.h
new file mode 100644
index 0000000000000000000000000000000000000000..512dda127dc995c7a3608ac32db504c4f3b3b7e3
--- /dev/null
+++ b/engine/src/Utils/StoryBoardElementType.h
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2025 Ansys, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+
+#pragma once
+#include <cstdint>
+
+namespace OpenScenarioEngine::v1_3
+{
+/// Definition of StoryBoardElementType
+///
+/// \see https://publications.pages.asam.net/standards/ASAM_OpenSCENARIO/ASAM_OpenSCENARIO_XML/latest/generated/content/StoryboardElementType.html
+enum class StoryBoardElementType : std::uint8_t
+{
+  kAct,
+  kAction,
+  kEvent,
+  kManeuver,
+  kManeuverGroup,
+  kStory,
+  kUnknown
+};
+}  // namespace OpenScenarioEngine::v1_3
diff --git a/engine/tests/Node/EventNodeTest.cpp b/engine/tests/Node/EventNodeTest.cpp
index 899c66c4800377ef907e605fad3d184951b057a7..2df19a3f7b8a0b5d6e88da8710ac721353186057 100644
--- a/engine/tests/Node/EventNodeTest.cpp
+++ b/engine/tests/Node/EventNodeTest.cpp
@@ -18,9 +18,11 @@
 #include "Node/EventNode.h"
 #include "Node/Testing/FakeActionNode.h"
 #include "TestUtils/MockEventPrioritizer.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 using OpenScenarioEngine::v1_3::EventPriority;
 using OpenScenarioEngine::v1_3::IEventPrioritizer;
+using OpenScenarioEngine::v1_3::StoryBoardElementStateManager;
 using OpenScenarioEngine::v1_3::Node::EventNode;
 using testing::Return;
 using testing::OpenScenarioEngine::v1_3::FakeActionNode;
@@ -30,13 +32,16 @@ class TreeWithPrioritizer
 {
 public:
   TreeWithPrioritizer()
-      : event_prioritizer_{std::make_shared<MockEventPrioritizer>()}
+      : event_prioritizer_{std::make_shared<MockEventPrioritizer>()}, story_board_element_state_manager_{std::make_shared<StoryBoardElementStateManager>()}
   {
-    auto declaration = std::make_unique<
-        yase::TypeDeclarer<
-            std::shared_ptr<
-                IEventPrioritizer>>>("EventPrioritizer", event_prioritizer_);
-    root_ = std::make_shared<yase::DataDeclarationNode>("RootWithEventPrioritizer", std::move(declaration));
+    std::vector<yase::DataDeclaration::UPtr> declarations;
+    declarations.push_back(std::make_unique<yase::TypeDeclarer<std::shared_ptr<IEventPrioritizer>>>(
+        "EventPrioritizer", event_prioritizer_));
+    declarations.push_back(std::make_unique<yase::TypeDeclarer<std::shared_ptr<StoryBoardElementStateManager>>>(
+        "StoryBoardElementStateManager", story_board_element_state_manager_));
+
+    root_ = std::make_shared<yase::DataDeclarationNode>(
+        "RootWithEventPrioritizer", std::move(declarations));
   }
 
   yase::DecoratorNode& get_root()
@@ -51,6 +56,7 @@ public:
 
 private:
   std::shared_ptr<MockEventPrioritizer> event_prioritizer_;
+  std::shared_ptr<StoryBoardElementStateManager> story_board_element_state_manager_;
   yase::DataDeclarationNode::Ptr root_;
 };
 
diff --git a/engine/tests/Node/ManeuverNodeTest.cpp b/engine/tests/Node/ManeuverNodeTest.cpp
index 310adc444e71af184d54cadc7e055423b4e6aa2b..f4bdfcde2ad57e0d92c845300123ac95f87345ba 100644
--- a/engine/tests/Node/ManeuverNodeTest.cpp
+++ b/engine/tests/Node/ManeuverNodeTest.cpp
@@ -8,8 +8,8 @@
  * SPDX-License-Identifier: EPL-2.0
  ********************************************************************************/
 
-#include <agnostic_behavior_tree/decorator/data_declaration_node.h>
 #include <agnostic_behavior_tree/composite/parallel_node.h>
+#include <agnostic_behavior_tree/decorator/data_declaration_node.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -18,12 +18,14 @@
 #include "Node/EventNode.h"
 #include "Node/ManeuverNode.h"
 #include "Node/Testing/FakeActionNode.h"
+#include "TestUtils.h"
 
 using OpenScenarioEngine::v1_3::EventPriority;
 using OpenScenarioEngine::v1_3::Node::EventNode;
 using OpenScenarioEngine::v1_3::Node::ManeuverNode;
 using testing::Return;
 using testing::OpenScenarioEngine::v1_3::FakeActionNode;
+using testing::OpenScenarioEngine::v1_3::FakeRootNode;
 
 enum class OscStatus : std::uint8_t
 {
@@ -42,6 +44,7 @@ protected:
   ManeuverNodeTest()
   {
     maneuver_node->setChild(events_node);
+    root_node->setChild(maneuver_node);
   }
 
   EventWithStartTrigger AddEventWithPriority(EventPriority priority)
@@ -96,6 +99,7 @@ protected:
 
   std::shared_ptr<ManeuverNode> maneuver_node = std::make_shared<ManeuverNode>("Maneuver Node");
   std::shared_ptr<yase::ParallelNode> events_node = std::make_shared<yase::ParallelNode>("Events Node");
+  std::shared_ptr<FakeRootNode> root_node = std::make_shared<FakeRootNode>(nullptr, nullptr, nullptr);
 };
 
 TEST_F(ManeuverNodeTest, GivenMultipleNodesWithParallelPriority_WhenManeuverTicks_ThenAllEventsRunning)
@@ -103,14 +107,14 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithParallelPriority_WhenManeuverTick
   auto [event1, start_trigger1] = AddEventWithPriority(EventPriority::kParallel);
   auto [event2, start_trigger2] = AddEventWithPriority(EventPriority::kParallel);
   auto [event3, start_trigger3] = AddEventWithPriority(EventPriority::kParallel);
-  maneuver_node->distributeData();
-  maneuver_node->executeTick();
+  root_node->distributeData();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event3, start_trigger3), OscStatus::kRunning);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kRunning);
@@ -122,8 +126,8 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithParallelorSkipPriority_WhenManeuv
   auto [event1, start_trigger1] = AddEventWithPriority(EventPriority::kParallel);
   auto [event2, start_trigger2] = AddEventWithPriority(EventPriority::kSkip);
   auto [event3, start_trigger3] = AddEventWithPriority(EventPriority::kParallel);
-  maneuver_node->distributeData();
-  maneuver_node->executeTick();
+  root_node->distributeData();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -137,15 +141,15 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithOneOverridePriority_WhenManeuverT
   auto [event3, start_trigger3] = AddEventWithPriority(EventPriority::kParallel);
   auto [event4, start_trigger4] = AddEventWithPriority(EventPriority::kOverride);
 
-  maneuver_node->distributeData();
-  maneuver_node->executeTick();
+  root_node->distributeData();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
   EXPECT_THAT(GetEventStatus(event3, start_trigger3), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event4, start_trigger4), OscStatus::kRunning);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kSuccess);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -157,28 +161,28 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithOneOverridePriority_WhenManeuverT
 {
   auto [event1, start_trigger1] = AddEventWithPriority(EventPriority::kParallel);
   EXPECT_CALL(start_trigger1, tick())
-    .WillOnce(Return(yase::NodeStatus::kRunning))
-    .WillRepeatedly(Return(yase::NodeStatus::kSuccess));
+      .WillOnce(Return(yase::NodeStatus::kRunning))
+      .WillRepeatedly(Return(yase::NodeStatus::kSuccess));
   auto [event2, start_trigger2] = AddEventWithPriority(EventPriority::kSkip);
   auto [event3, start_trigger3] = AddEventWithPriority(EventPriority::kParallel);
   auto [event4, start_trigger4] = AddEventWithPriority(EventPriority::kOverride);
 
-  maneuver_node->distributeData();
-  maneuver_node->executeTick();
+  root_node->distributeData();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kStandby);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
   EXPECT_THAT(GetEventStatus(event3, start_trigger3), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event4, start_trigger4), OscStatus::kRunning);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
   EXPECT_THAT(GetEventStatus(event3, start_trigger3), OscStatus::kSuccess);
   EXPECT_THAT(GetEventStatus(event4, start_trigger4), OscStatus::kRunning);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -186,7 +190,6 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithOneOverridePriority_WhenManeuverT
   EXPECT_THAT(GetEventStatus(event4, start_trigger4), OscStatus::kRunning);
 }
 
-
 TEST_F(ManeuverNodeTest, GivenMultipleNodesWithMultipleOverridePriority_WhenManeuverTicks_ThenOnlyStartedEventsOverridden)
 {
   auto [event1, start_trigger1] = AddEventWithPriority(EventPriority::kParallel);
@@ -195,16 +198,16 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithMultipleOverridePriority_WhenMane
   auto [event4, start_trigger4] = AddEventWithPriority(EventPriority::kOverride);
   auto [event5, start_trigger5] = AddEventWithPriority(EventPriority::kParallel);
   EXPECT_CALL(start_trigger5, tick())
-    .WillOnce(Return(yase::NodeStatus::kRunning))
-    .WillRepeatedly(Return(yase::NodeStatus::kSuccess));
+      .WillOnce(Return(yase::NodeStatus::kRunning))
+      .WillRepeatedly(Return(yase::NodeStatus::kSuccess));
   auto [event6, start_trigger6] = AddEventWithPriority(EventPriority::kOverride);
   EXPECT_CALL(start_trigger6, tick())
-    .WillOnce(Return(yase::NodeStatus::kRunning))
-    .WillOnce(Return(yase::NodeStatus::kRunning))
-    .WillRepeatedly(Return(yase::NodeStatus::kSuccess));
+      .WillOnce(Return(yase::NodeStatus::kRunning))
+      .WillOnce(Return(yase::NodeStatus::kRunning))
+      .WillRepeatedly(Return(yase::NodeStatus::kSuccess));
 
-  maneuver_node->distributeData();
-  maneuver_node->executeTick();
+  root_node->distributeData();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -213,7 +216,7 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithMultipleOverridePriority_WhenMane
   EXPECT_THAT(GetEventStatus(event5, start_trigger5), OscStatus::kStandby);
   EXPECT_THAT(GetEventStatus(event6, start_trigger6), OscStatus::kStandby);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kSuccess);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -222,7 +225,7 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithMultipleOverridePriority_WhenMane
   EXPECT_THAT(GetEventStatus(event5, start_trigger5), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event6, start_trigger6), OscStatus::kStandby);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kSuccess);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -231,7 +234,7 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithMultipleOverridePriority_WhenMane
   EXPECT_THAT(GetEventStatus(event5, start_trigger5), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event6, start_trigger6), OscStatus::kRunning);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kSuccess);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
@@ -241,7 +244,6 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithMultipleOverridePriority_WhenMane
   EXPECT_THAT(GetEventStatus(event6, start_trigger6), OscStatus::kRunning);
 }
 
-
 TEST_F(ManeuverNodeTest, GivenMultipleNodesWithOneOverwritePriority_WhenManeuverTicks_ThenParallelEventsOverridden)
 {
   auto [event1, start_trigger1] = AddEventWithPriority(EventPriority::kParallel);
@@ -249,15 +251,15 @@ TEST_F(ManeuverNodeTest, GivenMultipleNodesWithOneOverwritePriority_WhenManeuver
   auto [event3, start_trigger3] = AddEventWithPriority(EventPriority::kParallel);
   auto [event4, start_trigger4] = AddEventWithPriority(EventPriority::kOverwrite);
 
-  maneuver_node->distributeData();
-  maneuver_node->executeTick();
+  root_node->distributeData();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
   EXPECT_THAT(GetEventStatus(event3, start_trigger3), OscStatus::kRunning);
   EXPECT_THAT(GetEventStatus(event4, start_trigger4), OscStatus::kRunning);
 
-  maneuver_node->executeTick();
+  root_node->executeTick();
 
   EXPECT_THAT(GetEventStatus(event1, start_trigger1), OscStatus::kSuccess);
   EXPECT_THAT(GetEventStatus(event2, start_trigger2), OscStatus::kSkipped);
diff --git a/engine/tests/TestUtils.h b/engine/tests/TestUtils.h
index 7408a93901f80e061b9b836e83301df45aa70f45..7ad4c21a6f0b15b4eb45a8dea90880a0f43612da 100644
--- a/engine/tests/TestUtils.h
+++ b/engine/tests/TestUtils.h
@@ -1,6 +1,6 @@
 /*******************************************************************************
  * Copyright (c) 2021-2024, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
- * Copyright (c) 2023 Ansys, Inc.
+ * Copyright (c) 2023-2025 Ansys, Inc.
  *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -25,6 +25,7 @@
 #include "Utils/ControllerCreator.h"
 #include "Utils/EngineAbortFlags.h"
 #include "Utils/EntityBroker.h"
+#include "Utils/StoryBoardElementStateManager.h"
 
 namespace testing::OpenScenarioEngine::v1_3
 {
@@ -32,121 +33,124 @@ using namespace units::literals;
 
 class FakeRootNode : public yase::DecoratorNode
 {
-  public:
-    FakeRootNode(std::shared_ptr<mantle_api::IEnvironment> environment,
-                 std::shared_ptr<::OpenScenarioEngine::v1_3::EngineAbortFlags> engine_abort_flags,
-                 std::shared_ptr<::OpenScenarioEngine::v1_3::EntityBroker> entity_broker)
-        : yase::DecoratorNode{"OpenScenarioEngine"},
-          environment_{environment},
-          engine_abort_flags_{engine_abort_flags},
-          entity_broker_{entity_broker}
-    {
-        distributeData();
-    }
-
-  private:
-    void lookupAndRegisterData(yase::Blackboard& blackboard) override
-    {
-        blackboard.set("Environment", environment_);
-        blackboard.set("EngineAbortFlags", engine_abort_flags_);
-        blackboard.set("EntityBroker", entity_broker_);
-    }
-
-    yase::NodeStatus tick() final
-    {
-      return child().executeTick();
-    }
-
-    std::shared_ptr<mantle_api::IEnvironment> environment_;
-    std::shared_ptr<::OpenScenarioEngine::v1_3::EngineAbortFlags> engine_abort_flags_;
-    std::shared_ptr<::OpenScenarioEngine::v1_3::EntityBroker> entity_broker_;
+public:
+  FakeRootNode(std::shared_ptr<mantle_api::IEnvironment> environment,
+               std::shared_ptr<::OpenScenarioEngine::v1_3::EngineAbortFlags> engine_abort_flags,
+               std::shared_ptr<::OpenScenarioEngine::v1_3::EntityBroker> entity_broker)
+      : yase::DecoratorNode{"OpenScenarioEngine"},
+        environment_{environment},
+        engine_abort_flags_{engine_abort_flags},
+        entity_broker_{entity_broker},
+        story_board_element_state_manager_{std::make_shared<::OpenScenarioEngine::v1_3::StoryBoardElementStateManager>()}
+  {
+    distributeData();
+  }
+
+private:
+  void lookupAndRegisterData(yase::Blackboard& blackboard) override
+  {
+    blackboard.set("Environment", environment_);
+    blackboard.set("EngineAbortFlags", engine_abort_flags_);
+    blackboard.set("EntityBroker", entity_broker_);
+    blackboard.set("StoryBoardElementStateManager", story_board_element_state_manager_);
+  }
+
+  yase::NodeStatus tick() final
+  {
+    return child().executeTick();
+  }
+
+  std::shared_ptr<mantle_api::IEnvironment> environment_;
+  std::shared_ptr<::OpenScenarioEngine::v1_3::EngineAbortFlags> engine_abort_flags_;
+  std::shared_ptr<::OpenScenarioEngine::v1_3::EntityBroker> entity_broker_;
+  std::shared_ptr<::OpenScenarioEngine::v1_3::StoryBoardElementStateManager> story_board_element_state_manager_;
 };
 
 inline std::string GetScenariosPath(const std::string& test_file_path)
 {
-    std::filesystem::path file_path{test_file_path};
-    return {file_path.remove_filename().string() + "data/Scenarios/"};
+  std::filesystem::path file_path{test_file_path};
+  return {file_path.remove_filename().string() + "data/Scenarios/"};
 }
 
 class OpenScenarioEngineLibraryTestBase : public ::testing::Test
 {
-  protected:
-    void SetUp() override
-    {
-        env_ = std::make_shared<mantle_api::MockEnvironment>();
-        ON_CALL(env_->GetControllerRepository(), Create(testing::_)).WillByDefault(testing::ReturnRef(controller_));
-    }
-
-    std::shared_ptr<mantle_api::MockEnvironment> env_;
-    mantle_api::MockController controller_;
-    std::string default_xosc_scenario_{
-        "AutomatedLaneKeepingSystemScenarios/ALKS_Scenario_4.1_1_FreeDriving_TEMPLATE.xosc"};
+protected:
+  void SetUp() override
+  {
+    env_ = std::make_shared<mantle_api::MockEnvironment>();
+    ON_CALL(env_->GetControllerRepository(), Create(testing::_)).WillByDefault(testing::ReturnRef(controller_));
+  }
+
+  std::shared_ptr<mantle_api::MockEnvironment> env_;
+  mantle_api::MockController controller_;
+  std::string default_xosc_scenario_{
+      "AutomatedLaneKeepingSystemScenarios/ALKS_Scenario_4.1_1_FreeDriving_TEMPLATE.xosc"};
 };
 
 class EngineSubModuleTestBase : public OpenScenarioEngineLibraryTestBase
 {
-  protected:
-    virtual void LoadScenario(const std::string& scenario_file_path)
-    {
-        auto message_logger =
-            std::make_shared<NET_ASAM_OPENSCENARIO::SimpleMessageLogger>(NET_ASAM_OPENSCENARIO::ErrorLevel::INFO);
-        auto catalog_message_logger =
-            std::make_shared<NET_ASAM_OPENSCENARIO::SimpleMessageLogger>(NET_ASAM_OPENSCENARIO::ErrorLevel::INFO);
-        auto loader_factory =
-            NET_ASAM_OPENSCENARIO::v1_3::XmlScenarioImportLoaderFactory(catalog_message_logger, scenario_file_path);
-        auto loader = loader_factory.CreateLoader(std::make_shared<NET_ASAM_OPENSCENARIO::FileResourceLocator>());
-
-        scenario_ptr_ = std::static_pointer_cast<NET_ASAM_OPENSCENARIO::v1_3::IOpenScenario>(
-            loader->Load(message_logger)->GetAdapter(typeid(NET_ASAM_OPENSCENARIO::v1_3::IOpenScenario).name()));
-    }
-
-    std::string GetScenariosPath(const std::string& test_file_path) const
-    {
-        std::filesystem::path file_path{test_file_path};
-        // The first .parent_path() removes the filename, the second removes "/Utils"
-        return {file_path.parent_path().parent_path().string() + "/data/Scenarios/"};
-    }
-
-    std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::IOpenScenario> scenario_ptr_;
+protected:
+  virtual void LoadScenario(const std::string& scenario_file_path)
+  {
+    auto message_logger =
+        std::make_shared<NET_ASAM_OPENSCENARIO::SimpleMessageLogger>(NET_ASAM_OPENSCENARIO::ErrorLevel::INFO);
+    auto catalog_message_logger =
+        std::make_shared<NET_ASAM_OPENSCENARIO::SimpleMessageLogger>(NET_ASAM_OPENSCENARIO::ErrorLevel::INFO);
+    auto loader_factory =
+        NET_ASAM_OPENSCENARIO::v1_3::XmlScenarioImportLoaderFactory(catalog_message_logger, scenario_file_path);
+    auto loader = loader_factory.CreateLoader(std::make_shared<NET_ASAM_OPENSCENARIO::FileResourceLocator>());
+
+    scenario_ptr_ = std::static_pointer_cast<NET_ASAM_OPENSCENARIO::v1_3::IOpenScenario>(
+        loader->Load(message_logger)->GetAdapter(typeid(NET_ASAM_OPENSCENARIO::v1_3::IOpenScenario).name()));
+  }
+
+  std::string GetScenariosPath(const std::string& test_file_path) const
+  {
+    std::filesystem::path file_path{test_file_path};
+    // The first .parent_path() removes the filename, the second removes "/Utils"
+    return {file_path.parent_path().parent_path().string() + "/data/Scenarios/"};
+  }
+
+  std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_3::IOpenScenario> scenario_ptr_;
 };
 
 class OpenScenarioEngineTestBase : public OpenScenarioEngineLibraryTestBase
 {
-  protected:
-    void SetUp() override
-    {
-        OpenScenarioEngineLibraryTestBase::SetUp();
-
-        mantle_api::VehicleProperties ego_properties{};
-        ego_properties.type = mantle_api::EntityType::kVehicle;
-        ego_properties.classification = mantle_api::VehicleClass::kMedium_car;
-        ego_properties.model = "medium_car";
-        ego_properties.bounding_box.dimension.length = 5.0_m;
-        ego_properties.bounding_box.dimension.width = 2.0_m;
-        ego_properties.bounding_box.dimension.height = 1.8_m;
-        ego_properties.bounding_box.geometric_center.x = 1.4_m;
-        ego_properties.bounding_box.geometric_center.y = 0.0_m;
-        ego_properties.bounding_box.geometric_center.z = 0.9_m;
-        ego_properties.performance.max_acceleration = 10_mps_sq;
-        ego_properties.performance.max_deceleration = 10_mps_sq;
-        ego_properties.performance.max_speed = 70_mps;
-        ego_properties.front_axle.bb_center_to_axle_center = {1.58_m, 0.0_m, -0.5_m};
-        ego_properties.front_axle.max_steering = 0.5_rad;
-        ego_properties.front_axle.track_width = 1.68_m;
-        ego_properties.front_axle.wheel_diameter = 0.8_m;
-        ego_properties.rear_axle.bb_center_to_axle_center = {-1.4_m, 0.0_m, -0.5_m};
-        ego_properties.rear_axle.max_steering = 0_rad;
-        ego_properties.rear_axle.track_width = 1.68_m;
-        ego_properties.rear_axle.wheel_diameter = 0.8_m;
-        ego_properties.is_host = true;
-        // Necessary because Create() is always called in engine init and will otherwise not return a MockVehicle ref
-        // which results in an exception
-        ON_CALL(dynamic_cast<mantle_api::MockEntityRepository&>(env_->GetEntityRepository()),
-                Create(testing::_, ego_properties))
-            .WillByDefault(testing::ReturnRef(mock_vehicle_));
-    }
-
-    mantle_api::MockVehicle mock_vehicle_{};
+protected:
+  void SetUp() override
+  {
+    OpenScenarioEngineLibraryTestBase::SetUp();
+
+    mantle_api::VehicleProperties ego_properties{};
+    ego_properties.type = mantle_api::EntityType::kVehicle;
+    ego_properties.classification = mantle_api::VehicleClass::kMedium_car;
+    ego_properties.model = "medium_car";
+    ego_properties.bounding_box.dimension.length = 5.0_m;
+    ego_properties.bounding_box.dimension.width = 2.0_m;
+    ego_properties.bounding_box.dimension.height = 1.8_m;
+    ego_properties.bounding_box.geometric_center.x = 1.4_m;
+    ego_properties.bounding_box.geometric_center.y = 0.0_m;
+    ego_properties.bounding_box.geometric_center.z = 0.9_m;
+    ego_properties.performance.max_acceleration = 10_mps_sq;
+    ego_properties.performance.max_deceleration = 10_mps_sq;
+    ego_properties.performance.max_speed = 70_mps;
+    ego_properties.front_axle.bb_center_to_axle_center = {1.58_m, 0.0_m, -0.5_m};
+    ego_properties.front_axle.max_steering = 0.5_rad;
+    ego_properties.front_axle.track_width = 1.68_m;
+    ego_properties.front_axle.wheel_diameter = 0.8_m;
+    ego_properties.rear_axle.bb_center_to_axle_center = {-1.4_m, 0.0_m, -0.5_m};
+    ego_properties.rear_axle.max_steering = 0_rad;
+    ego_properties.rear_axle.track_width = 1.68_m;
+    ego_properties.rear_axle.wheel_diameter = 0.8_m;
+    ego_properties.is_host = true;
+    // Necessary because Create() is always called in engine init and will otherwise not return a MockVehicle ref
+    // which results in an exception
+    ON_CALL(dynamic_cast<mantle_api::MockEntityRepository&>(env_->GetEntityRepository()),
+            Create(testing::_, ego_properties))
+        .WillByDefault(testing::ReturnRef(mock_vehicle_));
+  }
+
+  mantle_api::MockVehicle mock_vehicle_{};
 };
 
 }  // namespace testing::OpenScenarioEngine::v1_3