diff --git a/Cargo.toml b/Cargo.toml
index db825c359a71188b057c58119fad3ed5ea1fcabd..3042bebc6f7d8c2405214f9211110b85f86f663a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,13 +15,9 @@ json_loader = ["serde", "dep:serde_json"]
 toml_loader = ["serde", "dep:toml"]
 serde = ["dep:serde"]
 
-ecs_tilemap = ["dep:bevy_ecs_tilemap"]
-
 [dependencies]
 anyhow = "^1.0.65"
 serde = { version = "^1.0.145", optional = true }
 serde_json = { version = "^1.0.85", optional = true }
 toml = { version = "0.7.4", optional = true }
-bevy = { version = "^0.11.0", default-features = false, features = ["bevy_asset", "bevy_sprite"] }
-
-bevy_ecs_tilemap = { version = "0.11.0", optional = true }
+bevy = { version = "^0.12.0", default-features = false, features = ["bevy_asset", "bevy_sprite"] }
diff --git a/src/definitions.rs b/src/definitions.rs
index 42b8a95ecd235bf27b4d96b32b966644557771df..c1c2096b3d9004b4134071bd578f894ad633acf9 100644
--- a/src/definitions.rs
+++ b/src/definitions.rs
@@ -1,5 +1,6 @@
 use std::collections::HashMap;
 use std::ops::{Deref, DerefMut};
+use std::time::Duration;
 
 use bevy::prelude::*;
 use bevy::reflect::TypeUuid;
@@ -14,59 +15,50 @@ pub struct AnimationFrames {
 }
 
 impl AnimationFrames {
-	pub fn len_secs(&self) -> f32 {
-		self.frames.len() as f32 * self.frame_secs
+	pub fn duration(&self) -> Duration {
+		Duration::from_secs_f32(self.frames.len() as f32 * self.frame_secs)
 	}
 }
 
-#[derive(Clone, Debug, TypeUuid, PartialEq, Default, Reflect)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Clone, Debug, TypeUuid, PartialEq, Default, Reflect, Deref, DerefMut)]
+#[cfg_attr(
+	feature = "serde",
+	derive(serde::Serialize, serde::Deserialize),
+	serde(transparent)
+)]
 #[uuid = "a2823f96-0f63-434e-9030-d8f762898a18"]
 pub struct AnimationSet(pub HashMap<String, AnimationFrames>);
-impl Deref for AnimationSet {
-	type Target = HashMap<String, AnimationFrames>;
 
-	fn deref(&self) -> &Self::Target {
-		&self.0
-	}
-}
-impl DerefMut for AnimationSet {
-	fn deref_mut(&mut self) -> &mut Self::Target {
-		&mut self.0
-	}
-}
-
-#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct SyncAnimationsToParent;
-
-#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
+#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct HasAnimations;
+pub struct SyncToParent;
 
-#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct HasSimpleAnimations;
-
-#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct HasDirectionalityAnimation;
-
-#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
+#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
 pub struct AnimationPaused;
 
-#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct AnimationUserData(pub u128);
-
-#[derive(Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)]
+#[cfg_attr(
+	feature = "serde",
+	derive(serde::Serialize, serde::Deserialize),
+	serde(transparent)
+)]
+pub struct UserData(pub u128);
+
+#[derive(Clone, Debug, Component, PartialEq, Eq, Default)]
+#[cfg_attr(
+	feature = "serde",
+	derive(serde::Serialize, serde::Deserialize),
+	serde(untagged, rename_all = "snake_case")
+)]
 pub enum AnimationMode {
 	#[default]
 	Loop,
 	Once,
-	OnceThenPlay(String),
+	IntroLoop {
+		intro: String,
+		r#loop: String,
+	},
 }
 
 #[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)]
@@ -78,14 +70,14 @@ pub struct AnimationStatus {
 }
 
 impl AnimationStatus {
-	pub fn assert_animation<T: ToString>(&mut self, name: T) {
+	pub fn set_animation(&mut self, name: impl ToString) {
 		self.active_name = name.to_string();
 	}
-	pub fn start_animation<T: ToString>(&mut self, name: T) {
+	pub fn start_animation(&mut self, name: impl ToString) {
 		self.active_name = name.to_string();
 		self.active_step = 0;
 	}
-	pub fn start_or_continue<T: ToString>(&mut self, name: T) {
+	pub fn start_or_continue(&mut self, name: impl ToString) {
 		let name = name.to_string();
 		if self.active_name != name {
 			self.active_name = name;
@@ -95,15 +87,14 @@ impl AnimationStatus {
 }
 
 #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)]
-pub struct DirectionalSpriteAnimationBundle {
+pub struct DirectionalAnimationBundle {
 	pub animation_handle: Handle<AnimationSet>,
 	pub mode: AnimationMode,
 	pub status: AnimationStatus,
 	pub direction: Directionality,
-	pub marker: HasDirectionalityAnimation,
 }
 
-impl DirectionalSpriteAnimationBundle {
+impl DirectionalAnimationBundle {
 	pub fn new(initial_anim: String, handle: Handle<AnimationSet>) -> Self {
 		Self {
 			animation_handle: handle,
@@ -114,10 +105,9 @@ impl DirectionalSpriteAnimationBundle {
 			},
 			mode: AnimationMode::Loop,
 			direction: Directionality::default(),
-			marker: HasDirectionalityAnimation,
 		}
 	}
-	pub fn with_initial_facing(
+	pub fn with_direction(
 		initial_anim: String,
 		handle: Handle<AnimationSet>,
 		direction: Directionality,
@@ -130,7 +120,6 @@ impl DirectionalSpriteAnimationBundle {
 				frame_time: 0.0,
 			},
 			mode: AnimationMode::Loop,
-			marker: HasDirectionalityAnimation,
 			direction,
 		}
 	}
@@ -141,7 +130,6 @@ pub struct SpriteAnimationBundle {
 	pub animation_handle: Handle<AnimationSet>,
 	pub mode: AnimationMode,
 	pub status: AnimationStatus,
-	pub marker: HasAnimations,
 }
 
 impl SpriteAnimationBundle {
@@ -154,98 +142,80 @@ impl SpriteAnimationBundle {
 				frame_time: 0.0,
 			},
 			mode: AnimationMode::Loop,
-			marker: HasAnimations,
 		}
 	}
 }
 
-#[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)]
-#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct SimpleLoopedAnimation {
-	pub frames: Vec<usize>,
-	pub frame_secs: f32,
+#[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default, Deref, DerefMut)]
+#[cfg_attr(
+	feature = "serde",
+	derive(serde::Serialize, serde::Deserialize),
+	serde(transparent)
+)]
+pub struct SimpleAnimation(pub AnimationFrames);
+impl From<AnimationFrames> for SimpleAnimation {
+	fn from(value: AnimationFrames) -> Self {
+		SimpleAnimation(value)
+	}
 }
 
 #[derive(Copy, Clone, Debug, Component, PartialEq, PartialOrd, Default)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct SimpleLoopedAnimationStatus {
+pub struct SimpleAnimationStatus {
 	pub active_step: usize,
 	pub frame_time: f32,
 }
 
 #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)]
 pub struct SimpleAnimationBundle {
-	pub anim: SimpleLoopedAnimation,
-	pub status: SimpleLoopedAnimationStatus,
-	pub marker: HasSimpleAnimations,
+	pub anim: SimpleAnimation,
+	pub status: SimpleAnimationStatus,
 }
 
 impl SimpleAnimationBundle {
 	pub fn new(frames: Vec<usize>, frame_secs: f32) -> Self {
 		SimpleAnimationBundle {
-			anim: SimpleLoopedAnimation { frames, frame_secs },
-			status: SimpleLoopedAnimationStatus {
+			anim: AnimationFrames { frames, frame_secs }.into(),
+			status: SimpleAnimationStatus {
 				active_step: 0,
 				frame_time: 0.0,
 			},
-			marker: HasSimpleAnimations,
 		}
 	}
 }
 
-#[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)]
+#[derive(Clone, Debug, Component, PartialEq, Eq, Default)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
 pub struct AnimationOverride {
 	pub name: String,
-	pub frame_step: usize,
-	pub frame_time: f32,
 	pub user_data: u128,
 }
-
 impl AnimationOverride {
-	pub fn new(name: String) -> Self {
-		Self {
-			name,
-			frame_time: 0.0,
-			frame_step: 0,
+	pub fn new(name: impl ToString) -> Self {
+		AnimationOverride {
+			name: name.to_string(),
 			user_data: 0,
 		}
 	}
-
-	pub fn new_with_user_data(name: String, user_data: u128) -> Self {
-		Self {
-			name,
+	pub fn with_user_data(name: impl ToString, user_data: u128) -> Self {
+		AnimationOverride {
+			name: name.to_string(),
 			user_data,
-			frame_step: 0,
-			frame_time: 0.0,
 		}
 	}
 }
-
+#[derive(Clone, Debug, Component, PartialEq, Eq, Default, Deref, DerefMut)]
 pub struct OverrideStatus(pub AnimationStatus);
 impl From<AnimationStatus> for OverrideStatus {
 	fn from(other: AnimationStatus) -> Self {
 		Self(other)
 	}
 }
-impl Deref for OverrideStatus {
-	type Target = AnimationStatus;
-
-	fn deref(&self) -> &Self::Target {
-		&self.0
-	}
-}
-impl DerefMut for OverrideStatus {
-	fn deref_mut(&mut self) -> &mut Self::Target {
-		&mut self.0
-	}
-}
 
 #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)]
 pub struct ChildAnimationBundle {
 	pub animation_handle: Handle<AnimationSet>,
-	pub status: AnimationStatus,
-	pub marker: SyncAnimationsToParent,
+	pub marker: SyncToParent,
 }
 
 impl ChildAnimationBundle {