diff --git a/Fatras/include/ActsFatras/Kernel/Interactor.hpp b/Fatras/include/ActsFatras/Kernel/Interactor.hpp
index 1c6c61f94726d6317c35a074922da97295416934..5a06a82be31c3db9186481b2db0e3e258a30e8d7 100644
--- a/Fatras/include/ActsFatras/Kernel/Interactor.hpp
+++ b/Fatras/include/ActsFatras/Kernel/Interactor.hpp
@@ -27,6 +27,28 @@ struct EverySurface {
   constexpr bool operator()(const Acts::Surface &) const { return true; }
 };
 
+/// Interactor result (and intermediate state).
+///
+/// The result struct does not depend on the template arguments of the
+/// Interactor. Defining it independently gives greater flexibility for its
+/// usage.
+struct InteractorResult {
+  /// Whether the simulation can continue, i.e. particle is still alive.
+  bool isAlive = true;
+  /// Accumulated material during the propagation.
+  /// The initial particle can already have some passed material. We need the
+  /// particle to store the full material path but still keep track of the
+  /// additional accumulated material during simulation.
+  Particle::Scalar pathInX0 = 0;
+  Particle::Scalar pathInL0 = 0;
+  /// Propagated particle state.
+  Particle particle;
+  /// Additional particles generated by interactions.
+  std::vector<Particle> generatedParticles;
+  /// Hits created by the propagated particle.
+  std::vector<Hit> hits;
+};
+
 /// Fatras interactor plugin for the Acts propagator.
 ///
 /// This plugin must be added to the action list of the propagator and is the
@@ -41,32 +63,7 @@ struct EverySurface {
 template <typename generator_t, typename physics_list_t,
           typename hit_surface_selector_t = NoSurface>
 struct Interactor {
-  /// Random number generator used for the simulation.
-  generator_t *generator = nullptr;
-  /// Physics list detailing the simulated interactions and processes.
-  physics_list_t physics;
-  /// Selector for surfaces that should generate hits.
-  hit_surface_selector_t selectHitSurface;
-  /// Initial particle state.
-  Particle particle;
-
-  /// Interaction result (and intermediate state).
-  struct result_type {
-    /// Whether the simulation can continue, i.e. particle is still alive.
-    bool isAlive = true;
-    /// Accumulated material during the propagation.
-    /// The initial particle can already have some passed material. We need the
-    /// particle to store the full material path but still keep track of the
-    /// additional accumulated material during simulation.
-    Particle::Scalar pathInX0 = 0;
-    Particle::Scalar pathInL0 = 0;
-    /// Propagated particle state.
-    Particle particle;
-    /// Additional particles generated by interactions.
-    std::vector<Particle> generatedParticles;
-    /// Hits created by the propagated particle.
-    std::vector<Hit> hits;
-  };
+  using result_type = InteractorResult;
 
   /// Abort if the particle was killed during a previous interaction.
   struct ParticleNotAlive {
@@ -80,6 +77,15 @@ struct Interactor {
     }
   };
 
+  /// Random number generator used for the simulation.
+  generator_t *generator = nullptr;
+  /// Physics list detailing the simulated interactions and processes.
+  physics_list_t physics;
+  /// Selector for surfaces that should generate hits.
+  hit_surface_selector_t selectHitSurface;
+  /// Initial particle state.
+  Particle particle;
+
   /// Simulate the interaction with a single surface.
   ///
   /// @tparam propagator_state_t is propagator state
diff --git a/Fatras/include/ActsFatras/Kernel/Simulator.hpp b/Fatras/include/ActsFatras/Kernel/Simulator.hpp
index d7004efd268335025dda8f4c69ebc0c190124736..5a821b32d31793660885b7c9a032a763623a5732 100644
--- a/Fatras/include/ActsFatras/Kernel/Simulator.hpp
+++ b/Fatras/include/ActsFatras/Kernel/Simulator.hpp
@@ -65,17 +65,15 @@ struct ParticleSimulator {
   ///
   /// @tparam generator_t is the type of the random number generator
   template <typename generator_t>
-  Acts::Result<typename Interactor<generator_t, physics_list_t,
-                                   hit_surface_selector_t>::result_type>
-  simulate(const Acts::GeometryContext &geoCtx,
-           const Acts::MagneticFieldContext &magCtx, generator_t &generator,
-           const Particle &particle) const {
+  Acts::Result<InteractorResult> simulate(
+      const Acts::GeometryContext &geoCtx,
+      const Acts::MagneticFieldContext &magCtx, generator_t &generator,
+      const Particle &particle) const {
     assert(localLogger and "Missing local logger");
 
     // propagator-related additional types
     using Interact =
         Interactor<generator_t, physics_list_t, hit_surface_selector_t>;
-    using InteractResult = typename Interact::result_type;
     using Actions = Acts::ActionList<Interact, Acts::detail::DebugOutputActor>;
     using Abort = Acts::AbortList<typename Interact::ParticleNotAlive,
                                   Acts::detail::EndOfWorldReached>;
@@ -103,7 +101,7 @@ struct ParticleSimulator {
           particle.time());
       auto result = propagator.propagate(start, options);
       if (result.ok()) {
-        return result.value().template get<InteractResult>();
+        return result.value().template get<InteractorResult>();
       } else {
         return result.error();
       }
@@ -113,7 +111,7 @@ struct ParticleSimulator {
           particle.absMomentum() * particle.unitDirection(), particle.time());
       auto result = propagator.propagate(start, options);
       if (result.ok()) {
-        return result.value().template get<InteractResult>();
+        return result.value().template get<InteractorResult>();
       } else {
         return result.error();
       }
@@ -252,11 +250,10 @@ struct Simulator {
 
   /// Copy Interactor results to output containers.
   ///
-  /// @tparam interactor_result_t is an Interactor result struct
   /// @tparam particles_t is a SequenceContainer for particles
   /// @tparam hits_t is a SequenceContainer for hits
-  template <typename interactor_result_t, typename particles_t, typename hits_t>
-  void copyOutputs(const interactor_result_t &result,
+  template <typename particles_t, typename hits_t>
+  void copyOutputs(const InteractorResult &result,
                    particles_t &particlesInitial, particles_t &particlesFinal,
                    hits_t &hits) const {
     // initial particle state was already pushed to the container before