diff --git a/Cargo.lock b/Cargo.lock
index 6b553a728cd5f9247dde3213b097a4195c83f013..74ea1ae09b585b7acb7b93ebe274ff6a6341d784 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2233,6 +2233,7 @@ version = "0.14.1"
 dependencies = [
  "bevy",
  "glam",
+ "log",
  "micro_autotile",
  "num-traits",
  "quadtree_rs",
diff --git a/Cargo.toml b/Cargo.toml
index 7ab6a1b629b576a4d14a7213b41c5ce20c891441..50b6872cf3bb26312459eb270808997aa9b5ccd7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,6 +39,7 @@ no_panic = []
 [dependencies]
 bevy = { optional = true, version = "0.15", default-features = false, features = ["bevy_render", "bevy_sprite", "bevy_asset", "serialize"] }
 
+log = "0.4"
 thiserror = "2.0"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
diff --git a/src/assets/asset_events.rs b/src/assets/asset_events.rs
index 578d71f5749c607e256bb5fe4e4946ae7b4dcb34..d3f5dd293a3cea394e030de9411bff6384a6134c 100644
--- a/src/assets/asset_events.rs
+++ b/src/assets/asset_events.rs
@@ -19,9 +19,10 @@ pub fn handle_ldtk_project_events(
 				if let Some(project) = assets.get(*id) {
 					for level in project.get_all_levels() {
 						if level.external_rel_path.is_none() {
-							
-							level_index
-								.insert(level.identifier.clone(), LdtkLevel::from_project(&project, level.clone()));
+							level_index.insert(
+								level.identifier.clone(),
+								LdtkLevel::from_project(project, level.clone()),
+							);
 							update_events.send(LevelDataUpdated(level.identifier.clone()));
 						}
 					}
diff --git a/src/camera.rs b/src/camera.rs
index f60d30ada688e61356ce8fe96fd34c81edffd164..ef87736ad624195c74b3f283d344f0df458a32e7 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -34,7 +34,7 @@ pub struct CameraBounder<'w, 's, Filter: QueryFilter + 'static> {
 	map_query: MapQuery<'w>,
 	query: Query<'w, 's, &'static OrthographicProjection, Filter>,
 }
-impl<'w, 's, Filter: QueryFilter + 'static> CameraBounder<'w, 's, Filter> {
+impl<Filter: QueryFilter + 'static> CameraBounder<'_, '_, Filter> {
 	pub fn get_extremeties(&self) -> Option<Rect> {
 		if let Some(bounds) = self.map_query.get_camera_bounds() {
 			if let Ok(proj) = self.query.get_single() {
diff --git a/src/ldtk/mod.rs b/src/ldtk/mod.rs
index 53aa94e01d45273d1ba04bccfe0aed340928c492..c303cb8ad3146349497c6a419efe61c78aed611d 100644
--- a/src/ldtk/mod.rs
+++ b/src/ldtk/mod.rs
@@ -19,7 +19,6 @@ mod data_1_4_0;
 #[cfg(any(feature = "ldtk_1_5_3"))]
 mod data_1_5_3;
 
-
 use crate::ldtk;
 #[cfg(feature = "ldtk_1_0_0")]
 pub use data_1_0_0::*;
@@ -79,8 +78,8 @@ macro_rules! impl_from_bytes {
 	};
 }
 
-impl<'a> LdtkFromBytes<'a> for Level {}
-impl<'a> LdtkFromBytes<'a> for Project {}
+impl LdtkFromBytes<'_> for Level {}
+impl LdtkFromBytes<'_> for Project {}
 
 impl_from_bytes!(Level);
 impl_from_bytes!(Project);
@@ -89,11 +88,12 @@ impl_from_bytes!(Project);
 mod _bevy_impl {
 	use super::*;
 	use bevy::asset::io::Reader;
-	use bevy::asset::{AssetLoader, AsyncReadExt, LoadContext, UntypedAssetId, VisitAssetDependencies};
+	use bevy::asset::{
+		AssetLoader, AsyncReadExt, LoadContext, UntypedAssetId, VisitAssetDependencies,
+	};
 	use bevy::prelude::{Asset, Handle};
 	use bevy::reflect::TypePath;
 
-
 	impl TypePath for Project {
 		fn type_path() -> &'static str {
 			"micro_ldtk::ldtk::Project"
@@ -124,7 +124,6 @@ mod _bevy_impl {
 
 	impl Asset for Level {}
 
-
 	#[derive(Asset, TypePath)]
 	pub struct LevelSet(pub Vec<Handle<Level>>);
 
@@ -149,12 +148,6 @@ mod _bevy_impl {
 				.levels
 				.iter()
 				.flat_map(|level| {
-					log::debug!(
-					"Checking if level is external: {} [{}]",
-					level.identifier,
-					level.external_rel_path.is_some()
-				);
-
 					level
 						.external_rel_path
 						.as_ref()
@@ -210,7 +203,7 @@ mod _bevy_impl {
 }
 
 #[cfg(feature = "bevy")]
-pub use _bevy_impl::{LdtkLoader, LdtkLevelLoader, LevelSet};
+pub use _bevy_impl::{LdtkLevelLoader, LdtkLoader, LevelSet};
 
 impl Project {
 	pub fn get_all_levels(&self) -> Vec<&Level> {
@@ -252,7 +245,6 @@ pub enum LdtkLoadError {
 
 pub type LdtkProject = Project;
 
-
 #[cfg(feature = "autotile")]
 mod autotile_support {
 	use micro_autotile::{AutoRuleSet, AutoTileRule, TileMatcher, TileOutput, TileStatus};
@@ -284,21 +276,15 @@ mod autotile_support {
 					1 => Some(AutoTileRule {
 						chance: rule.chance as f32,
 						output: create_output(rule),
-						matcher: TileMatcher::single(TileStatus::from(
-							rule.pattern[0],
-						)),
+						matcher: TileMatcher::single(TileStatus::from(rule.pattern[0])),
 					}),
-					_ => {
-						TileMatcher::try_from(rule.pattern.as_slice())
-							.ok().map(|matcher| {
-							AutoTileRule {
-								matcher,
-								chance: rule.chance as f32,
-                                output: create_output(rule),
-							}
-						})
-
-					}
+					_ => TileMatcher::try_from(rule.pattern.as_slice())
+						.ok()
+						.map(|matcher| AutoTileRule {
+							matcher,
+							chance: rule.chance as f32,
+							output: create_output(rule),
+						}),
 				})
 				.collect();
 
diff --git a/src/lib.rs b/src/lib.rs
index c33749b12ba94b6831165e8901a5b6f67431be36..82d7392a3428511aec24e57eacdab8cf79aecf5a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -66,7 +66,7 @@ mod __plugin {
 	impl<CameraFilter: QueryFilter + Send + Sync + 'static> MicroLDTKCameraPlugin<CameraFilter> {
 		pub fn new() -> Self {
 			Self {
-				_p: PhantomData::default(),
+				_p: PhantomData,
 			}
 		}
 	}
@@ -93,19 +93,19 @@ mod __plugin {
 	}
 }
 
-use std::sync::atomic::{AtomicU32, Ordering};
 #[cfg(feature = "bevy")]
 pub use __plugin::{MicroLDTKCameraPlugin, MicroLDTKPlugin};
 #[cfg(feature = "bevy")]
 pub use assets::{LevelIndex, TileMetadata, TilesetIndex};
 #[cfg(feature = "bevy")]
 pub use camera::CameraBounder;
-pub use ldtk::{LdtkProject, Level, AutoLayerRuleGroup};
 #[cfg(feature = "bevy")]
 pub use ldtk::LdtkLoader;
+pub use ldtk::{AutoLayerRuleGroup, LdtkProject, Level};
 pub use map_query::{CameraBounds, InstanceRef, MapQuery};
 #[cfg(feature = "autotile")]
 pub use micro_autotile as autotile;
 #[cfg(feature = "bevy")]
 pub use pregen::{write_layer_to_texture, write_map_to_texture, Rasterise};
+use std::sync::atomic::{AtomicU32, Ordering};
 pub use system::*;
diff --git a/src/map_query.rs b/src/map_query.rs
index a38040fe38edab04a1dfa75c1200077e1d2e0b18..b6723ce13e8d82af138fc8904deac9d2b1a8f9d7 100644
--- a/src/map_query.rs
+++ b/src/map_query.rs
@@ -114,7 +114,7 @@ impl<'a> InstanceRef<'a> {
 	}
 }
 
-impl<'a, T: ToString> Index<T> for InstanceRef<'a> {
+impl<T: ToString> Index<T> for InstanceRef<'_> {
 	type Output = serde_json::Value;
 
 	fn index(&self, index: T) -> &Self::Output {
@@ -152,7 +152,7 @@ impl CameraBounds {
 	}
 }
 
-impl<'w> MapQuery<'w> {
+impl MapQuery<'_> {
 	// --- We put our logic in static accessors because we might source a level other
 	// --- than the currently active one. 'active' methods are a convenience to
 	// --- call the static accessors on whatever the current level is
diff --git a/src/map_query_neutral.rs b/src/map_query_neutral.rs
index 441000a0eb3af47b8fbbf7ce1271678a8ce2a6d2..c0709f7a1fd965c991c908835cfc7a17250fdcb9 100644
--- a/src/map_query_neutral.rs
+++ b/src/map_query_neutral.rs
@@ -9,230 +9,230 @@ pub struct MapQuery {}
 
 #[derive(Clone)]
 pub struct InstanceRef<'a> {
-    pub entity: &'a EntityInstance,
+	pub entity: &'a EntityInstance,
 }
 
 impl<'a> InstanceRef<'a> {
-    /// Get the leftmost pixel of this entity's anchor point
-    pub fn x(&self) -> i64 {
-        self.entity.px[0]
-    }
-    /// Get the topmost pixel of this entity's anchor point
-    pub fn y(&self) -> i64 {
-        self.entity.px[1]
-    }
-    /// Get the pixel width of this entity
-    pub fn width(&self) -> i64 {
-        self.entity.width
-    }
-    /// Get the pixel width of this entity
-    pub fn height(&self) -> i64 {
-        self.entity.height
-    }
-
-    /// Get the category that this instance belongs to. Exactly matches the string name
-    /// found in the LDTK entities list
-    pub fn get_type(&self) -> &'a String {
-        &self.entity.identifier
-    }
-    /// Try to get a type safe representation of this entity's type, as long as the target type
-    /// can be produced from a [str] representation
-    ///
-    /// ## Example
-    ///
-    /// ```
-    /// # use std::str::FromStr;
-    /// # use micro_ldtk::InstanceRef;
-    /// # use micro_ldtk::ldtk::EntityInstance;
-    ///
-    /// #[derive(PartialEq, Debug)]
-    /// enum MyEntityType {
-    ///     Player,
-    ///     Monster,
-    /// }
-    ///
-    /// impl FromStr for MyEntityType {
-    /// #    type Err = ();
-    ///     fn from_str(s: &str) -> Result<Self, Self::Err> {
-    ///         match s {
-    ///             "player" => Ok(Self::Player),
-    ///             "monster" => Ok(Self::Monster),
-    /// #            _ => panic!("Oh no")
-    ///         }
-    ///     }
-    /// }
-    ///
-    /// let data_from_ldtk: EntityInstance = EntityInstance {
-    ///     identifier: "player".to_string(),
-    ///     // ...other properties
-    /// #         smart_color: "".to_string(),
-    /// #         grid: vec![],
-    /// #         pivot: vec![],
-    /// #         tags: vec![],
-    /// #         tile: None,
-    /// #         world_x: None,
-    /// #         world_y: None,
-    /// #         def_uid: 0,
-    /// #         field_instances: vec![],
-    /// #         height: 0,
-    /// #         iid: "".to_string(),
-    /// #         px: vec![],
-    /// #         width: 0,
-    /// };
-    /// #
-    /// # let process_ldtk_data = || -> InstanceRef<'_> {
-    /// #     InstanceRef {
-    /// #         entity: &data_from_ldtk,
-    /// #     }
-    /// # };
-    ///
-    /// let my_entity_type: InstanceRef<'_> = process_ldtk_data();
-    /// assert_eq!(my_entity_type.try_get_typed_id(), Ok(MyEntityType::Player));
-    /// ```
-    pub fn try_get_typed_id<T: FromStr>(&self) -> Result<T, T::Err> {
-        T::from_str(self.get_type().as_str())
-    }
-
-    /// Retrieve an associated property from this instance. Will return [serde_json::Value::Null]
-    /// if there is no property with the given name
-    pub fn property(&self, name: impl ToString) -> serde_json::Value {
-        self[name].clone()
-    }
-
-    /// Get a reference to the inner instance of this instance ref
-    pub fn instance_ref(&self) -> &EntityInstance {
-        self.entity
-    }
+	/// Get the leftmost pixel of this entity's anchor point
+	pub fn x(&self) -> i64 {
+		self.entity.px[0]
+	}
+	/// Get the topmost pixel of this entity's anchor point
+	pub fn y(&self) -> i64 {
+		self.entity.px[1]
+	}
+	/// Get the pixel width of this entity
+	pub fn width(&self) -> i64 {
+		self.entity.width
+	}
+	/// Get the pixel width of this entity
+	pub fn height(&self) -> i64 {
+		self.entity.height
+	}
+
+	/// Get the category that this instance belongs to. Exactly matches the string name
+	/// found in the LDTK entities list
+	pub fn get_type(&self) -> &'a String {
+		&self.entity.identifier
+	}
+	/// Try to get a type safe representation of this entity's type, as long as the target type
+	/// can be produced from a [str] representation
+	///
+	/// ## Example
+	///
+	/// ```
+	/// # use std::str::FromStr;
+	/// # use micro_ldtk::InstanceRef;
+	/// # use micro_ldtk::ldtk::EntityInstance;
+	///
+	/// #[derive(PartialEq, Debug)]
+	/// enum MyEntityType {
+	///     Player,
+	///     Monster,
+	/// }
+	///
+	/// impl FromStr for MyEntityType {
+	/// #    type Err = ();
+	///     fn from_str(s: &str) -> Result<Self, Self::Err> {
+	///         match s {
+	///             "player" => Ok(Self::Player),
+	///             "monster" => Ok(Self::Monster),
+	/// #            _ => panic!("Oh no")
+	///         }
+	///     }
+	/// }
+	///
+	/// let data_from_ldtk: EntityInstance = EntityInstance {
+	///     identifier: "player".to_string(),
+	///     // ...other properties
+	/// #         smart_color: "".to_string(),
+	/// #         grid: vec![],
+	/// #         pivot: vec![],
+	/// #         tags: vec![],
+	/// #         tile: None,
+	/// #         world_x: None,
+	/// #         world_y: None,
+	/// #         def_uid: 0,
+	/// #         field_instances: vec![],
+	/// #         height: 0,
+	/// #         iid: "".to_string(),
+	/// #         px: vec![],
+	/// #         width: 0,
+	/// };
+	/// #
+	/// # let process_ldtk_data = || -> InstanceRef<'_> {
+	/// #     InstanceRef {
+	/// #         entity: &data_from_ldtk,
+	/// #     }
+	/// # };
+	///
+	/// let my_entity_type: InstanceRef<'_> = process_ldtk_data();
+	/// assert_eq!(my_entity_type.try_get_typed_id(), Ok(MyEntityType::Player));
+	/// ```
+	pub fn try_get_typed_id<T: FromStr>(&self) -> Result<T, T::Err> {
+		T::from_str(self.get_type().as_str())
+	}
+
+	/// Retrieve an associated property from this instance. Will return [serde_json::Value::Null]
+	/// if there is no property with the given name
+	pub fn property(&self, name: impl ToString) -> serde_json::Value {
+		self[name].clone()
+	}
+
+	/// Get a reference to the inner instance of this instance ref
+	pub fn instance_ref(&self) -> &EntityInstance {
+		self.entity
+	}
 }
 
-impl<'a, T: ToString> Index<T> for InstanceRef<'a> {
-    type Output = serde_json::Value;
+impl<T: ToString> Index<T> for InstanceRef<'_> {
+	type Output = serde_json::Value;
 
-    fn index(&self, index: T) -> &Self::Output {
-        let name = index.to_string();
-        for field in &self.entity.field_instances {
-            if field.identifier == name {
-                return field.value.as_ref().unwrap_or(&serde_json::Value::Null);
-            }
-        }
+	fn index(&self, index: T) -> &Self::Output {
+		let name = index.to_string();
+		for field in &self.entity.field_instances {
+			if field.identifier == name {
+				return field.value.as_ref().unwrap_or(&serde_json::Value::Null);
+			}
+		}
 
-        &serde_json::Value::Null
-    }
+		&serde_json::Value::Null
+	}
 }
 
 #[derive(Copy, Clone, Debug)]
 pub struct CameraBounds {
-    pub left: f32,
-    pub top: f32,
-    pub bottom: f32,
-    pub right: f32,
+	pub left: f32,
+	pub top: f32,
+	pub bottom: f32,
+	pub right: f32,
 }
 
 impl CameraBounds {
-    pub fn get_min_x(&self, camera_width: f32) -> f32 {
-        self.left + (camera_width / 2.0) // - (get_ldtk_tile_scale() / 2.0)
-    }
-    pub fn get_max_x(&self, camera_width: f32) -> f32 {
-        self.right - (camera_width / 2.0) // - (get_ldtk_tile_scale() / 2.0)
-    }
-    pub fn get_min_y(&self, camera_height: f32) -> f32 {
-        self.bottom + (camera_height / 2.0) // - (get_ldtk_tile_scale() / 2.0)
-    }
-    pub fn get_max_y(&self, camera_height: f32) -> f32 {
-        self.top - (camera_height / 2.0) // - (get_ldtk_tile_scale() / 2.0)
-    }
+	pub fn get_min_x(&self, camera_width: f32) -> f32 {
+		self.left + (camera_width / 2.0) // - (get_ldtk_tile_scale() / 2.0)
+	}
+	pub fn get_max_x(&self, camera_width: f32) -> f32 {
+		self.right - (camera_width / 2.0) // - (get_ldtk_tile_scale() / 2.0)
+	}
+	pub fn get_min_y(&self, camera_height: f32) -> f32 {
+		self.bottom + (camera_height / 2.0) // - (get_ldtk_tile_scale() / 2.0)
+	}
+	pub fn get_max_y(&self, camera_height: f32) -> f32 {
+		self.top - (camera_height / 2.0) // - (get_ldtk_tile_scale() / 2.0)
+	}
 }
 
 impl MapQuery {
-    // --- We put our logic in static accessors because we might source a level other
-    // --- than the currently active one. 'active' methods are a convenience to
-    // --- call the static accessors on whatever the current level is
-
-    /// Perform an action on each layer of the given LDTK level
-    pub fn for_each_layer_of(level: &LdtkLevel, mut cb: impl FnMut(&LdtkLayer)) {
-        for layer in level.layers() {
-            cb(layer);
-        }
-    }
-
-    /// Retrieve an iterator over every layer in the given level, regardless of type
-    pub fn get_layers_of(level: &LdtkLevel) -> impl DoubleEndedIterator<Item = &LdtkLayer> {
-        level.layers()
-    }
-
-    /// Retrieve a reference to every entity stored in the given level, regardless of which layer it is found on
-    pub fn get_entities_of(level: &LdtkLevel) -> Vec<&EntityInstance> {
-        level
-            .layers()
-            .flat_map(|layer| layer.as_ref().entity_instances.iter())
-            .collect()
-    }
-
-    /// Retrieve an enhanced wrapper to every entity stored in the given level, regardless of which layer it is found on
-    pub fn get_instance_refs_of(level: &LdtkLevel) -> Vec<InstanceRef> {
-        level
-            .layers()
-            .flat_map(|layer| {
-                layer
-                    .as_ref()
-                    .entity_instances
-                    .iter()
-                    .map(|inst| InstanceRef { entity: inst })
-            })
-            .collect()
-    }
-
-    /// Retrieve a reference to every entity stored in the given level that matches the specified type name.
-    /// This must exactly match the name shown in the LDTK entity list
-    pub fn get_filtered_entities_of(
-        level: &LdtkLevel,
-        entity_type: impl ToString,
-    ) -> Vec<&EntityInstance> {
-        let e_type = entity_type.to_string();
-        level
-            .layers()
-            .flat_map(|layer| layer.as_ref().entity_instances.iter())
-            .filter(|inst| inst.identifier == e_type)
-            .collect()
-    }
-
-    /// Retrieve an enhanced wrapper to every entity stored in the given level that matches the specified type name.
-    /// This must exactly match the name shown in the LDTK entity list
-    pub fn get_filtered_instance_refs_of(
-        level: &LdtkLevel,
-        entity_type: impl ToString,
-    ) -> Vec<InstanceRef> {
-        let e_type = entity_type.to_string();
-        level
-            .layers()
-            .flat_map(|layer| {
-                layer
-                    .as_ref()
-                    .entity_instances
-                    .iter()
-                    .map(|inst| InstanceRef { entity: inst })
-            })
-            .filter(|inst| inst.entity.identifier == e_type)
-            .collect()
-    }
-
-    /// Retrieve an owned copy of all entity data in the given level
-    pub fn get_owned_entities_of(level: &LdtkLevel) -> Vec<EntityInstance> {
-        level
-            .layers()
-            .flat_map(|layer| layer.as_ref().entity_instances.iter().cloned())
-            .collect()
-    }
-
-    /// Use the size of the level to create a zero-based rectangle indicating the boundaries that a camera should
-    ///stay within to avoid showing any out-of-level space
-    pub fn get_camera_bounds_of(level: &LdtkLevel) -> CameraBounds {
-        let level = level.level_ref();
-        CameraBounds {
-            left: 0.0,
-            top: level.px_hei as f32,
-            bottom: 0.0,
-            right: level.px_wid as f32,
-        }
-    }
+	// --- We put our logic in static accessors because we might source a level other
+	// --- than the currently active one. 'active' methods are a convenience to
+	// --- call the static accessors on whatever the current level is
+
+	/// Perform an action on each layer of the given LDTK level
+	pub fn for_each_layer_of(level: &LdtkLevel, mut cb: impl FnMut(&LdtkLayer)) {
+		for layer in level.layers() {
+			cb(layer);
+		}
+	}
+
+	/// Retrieve an iterator over every layer in the given level, regardless of type
+	pub fn get_layers_of(level: &LdtkLevel) -> impl DoubleEndedIterator<Item = &LdtkLayer> {
+		level.layers()
+	}
+
+	/// Retrieve a reference to every entity stored in the given level, regardless of which layer it is found on
+	pub fn get_entities_of(level: &LdtkLevel) -> Vec<&EntityInstance> {
+		level
+			.layers()
+			.flat_map(|layer| layer.as_ref().entity_instances.iter())
+			.collect()
+	}
+
+	/// Retrieve an enhanced wrapper to every entity stored in the given level, regardless of which layer it is found on
+	pub fn get_instance_refs_of(level: &LdtkLevel) -> Vec<InstanceRef> {
+		level
+			.layers()
+			.flat_map(|layer| {
+				layer
+					.as_ref()
+					.entity_instances
+					.iter()
+					.map(|inst| InstanceRef { entity: inst })
+			})
+			.collect()
+	}
+
+	/// Retrieve a reference to every entity stored in the given level that matches the specified type name.
+	/// This must exactly match the name shown in the LDTK entity list
+	pub fn get_filtered_entities_of(
+		level: &LdtkLevel,
+		entity_type: impl ToString,
+	) -> Vec<&EntityInstance> {
+		let e_type = entity_type.to_string();
+		level
+			.layers()
+			.flat_map(|layer| layer.as_ref().entity_instances.iter())
+			.filter(|inst| inst.identifier == e_type)
+			.collect()
+	}
+
+	/// Retrieve an enhanced wrapper to every entity stored in the given level that matches the specified type name.
+	/// This must exactly match the name shown in the LDTK entity list
+	pub fn get_filtered_instance_refs_of(
+		level: &LdtkLevel,
+		entity_type: impl ToString,
+	) -> Vec<InstanceRef> {
+		let e_type = entity_type.to_string();
+		level
+			.layers()
+			.flat_map(|layer| {
+				layer
+					.as_ref()
+					.entity_instances
+					.iter()
+					.map(|inst| InstanceRef { entity: inst })
+			})
+			.filter(|inst| inst.entity.identifier == e_type)
+			.collect()
+	}
+
+	/// Retrieve an owned copy of all entity data in the given level
+	pub fn get_owned_entities_of(level: &LdtkLevel) -> Vec<EntityInstance> {
+		level
+			.layers()
+			.flat_map(|layer| layer.as_ref().entity_instances.iter().cloned())
+			.collect()
+	}
+
+	/// Use the size of the level to create a zero-based rectangle indicating the boundaries that a camera should
+	///stay within to avoid showing any out-of-level space
+	pub fn get_camera_bounds_of(level: &LdtkLevel) -> CameraBounds {
+		let level = level.level_ref();
+		CameraBounds {
+			left: 0.0,
+			top: level.px_hei as f32,
+			bottom: 0.0,
+			right: level.px_wid as f32,
+		}
+	}
 }
diff --git a/src/pregen.rs b/src/pregen.rs
index 4078fa2c6d5f4a32d81a3f8d191d03f163dac5a9..d2e58989b487d742e19a040c986af65c89d64c4f 100644
--- a/src/pregen.rs
+++ b/src/pregen.rs
@@ -1,6 +1,6 @@
-use bevy::prelude::{Image, TextureAtlas};
-use bevy::render::render_resource::TextureFormat;
 use bevy::image::TextureFormatPixelInfo;
+use bevy::prelude::Image;
+use bevy::render::render_resource::TextureFormat;
 use bevy::sprite::TextureAtlasLayout;
 
 use crate::{
diff --git a/src/system/types.rs b/src/system/types.rs
index b7497b8ed29bbc22584a28c225d57fc934fadc38..0cb96c3a21580d737e2597e29194dc34f55cb79d 100644
--- a/src/system/types.rs
+++ b/src/system/types.rs
@@ -18,8 +18,8 @@ use serde_json::{Map, Number, Value};
 
 use crate::ldtk::{EntityInstance, FieldInstance, LayerInstance, Level, Project, TileInstance};
 use crate::system::Indexer;
-use crate::{get_ldtk_tile_scale, px_to_grid};
 use crate::MapQuery;
+use crate::{get_ldtk_tile_scale, px_to_grid};
 
 mod compat;
 
@@ -73,7 +73,7 @@ impl<'a> TileRef<'a> {
 	}
 }
 
-impl<'a> Debug for TileRef<'a> {
+impl Debug for TileRef<'_> {
 	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 		f.debug_struct("TileRef")
 			.field("gid", &self.gid())
@@ -122,9 +122,12 @@ impl LdtkLevel {
 		#[cfg(feature = "_supports_ui_tags")]
 		{
 			level_data.layers_mut().for_each(|layer| {
-				if let Some(def) = project.defs.layers.iter().find(|inner| {
-					inner.uid == layer.layer.layer_def_uid
-				}) {
+				if let Some(def) = project
+					.defs
+					.layers
+					.iter()
+					.find(|inner| inner.uid == layer.layer.layer_def_uid)
+				{
 					layer.tags = def.ui_filter_tags.clone();
 				}
 			});
@@ -176,7 +179,6 @@ impl LdtkLevel {
 	pub fn get_indexer(&self) -> Indexer {
 		Indexer::new(px_to_grid(self.level.px_wid), px_to_grid(self.level.px_hei))
 	}
-
 }
 
 #[derive(Debug, Clone, Default)]
diff --git a/src/system/utils.rs b/src/system/utils.rs
index 0b03580a841275a25c0489f9d02d34c3a43c5577..e3469ad24468173ca34cbe139d90a8851bf674ee 100644
--- a/src/system/utils.rs
+++ b/src/system/utils.rs
@@ -56,7 +56,7 @@ impl Indexer {
 	pub fn index(&self, x: impl AsPrimitive<i64>, y: impl AsPrimitive<i64>) -> usize {
 		match (self.width(), self.height()) {
 			(0, _) | (_, 0) => 0,
-            (w, _) => ((y.as_() * w) + x.as_()).as_(),
+			(w, _) => ((y.as_() * w) + x.as_()).as_(),
 		}
 	}
 
@@ -76,10 +76,10 @@ impl Indexer {
 		let index = index.as_();
 		match index {
 			0 => (0, 0),
-            _ => (
+			_ => (
 				index.checked_rem(self.width).unwrap_or(0) as usize,
 				index.checked_div(self.width).unwrap_or(0) as usize,
-			)
+			),
 		}
 	}
 
diff --git a/tests/indexer.rs b/tests/indexer.rs
index c20979ef41500c10fe5346e5955e25b1e03e8d39..9a786d811a1b2f3aa8632ccecce315c2d7537b49 100644
--- a/tests/indexer.rs
+++ b/tests/indexer.rs
@@ -1,5 +1,5 @@
-use micro_ldtk::Indexer;
 use glam::IVec2;
+use micro_ldtk::Indexer;
 use num_traits::AsPrimitive;
 use test_case::test_case;
 
@@ -10,9 +10,12 @@ use test_case::test_case;
 #[test_case(2, 2 => 12)]
 #[test_case(1i32, 1i32 => 6)]
 #[test_case(2.5f32, 1.2f32 => 7)] // Floating point coordinates are truncated
-fn test_indexer_calculates_correct_index(x: impl AsPrimitive<i64>, y: impl AsPrimitive<i64>) -> usize {
-    let indexer = Indexer::new(5, 4);
-    indexer.index(x, y)
+fn test_indexer_calculates_correct_index(
+	x: impl AsPrimitive<i64>,
+	y: impl AsPrimitive<i64>,
+) -> usize {
+	let indexer = Indexer::new(5, 4);
+	indexer.index(x, y)
 }
 
 #[test_case(0 => (0, 0))]
@@ -22,8 +25,8 @@ fn test_indexer_calculates_correct_index(x: impl AsPrimitive<i64>, y: impl AsPri
 #[test_case(10 => (0, 2))]
 #[test_case(14 => (4, 2))]
 fn test_indexer_reverse(index: usize) -> (usize, usize) {
-    let indexer = Indexer::new(5, 3);
-    indexer.reverse(index)
+	let indexer = Indexer::new(5, 3);
+	indexer.reverse(index)
 }
 
 #[test_case(0, 0)]
@@ -32,11 +35,11 @@ fn test_indexer_reverse(index: usize) -> (usize, usize) {
 #[test_case(2, 2)]
 #[test_case(4, 2)]
 fn test_index_is_reflexive(x: usize, y: usize) {
-    let indexer = Indexer::new(5, 3);
-    let idx = indexer.index(x, y);
-    let (x_rev, y_rev) = indexer.reverse(idx);
+	let indexer = Indexer::new(5, 3);
+	let idx = indexer.index(x, y);
+	let (x_rev, y_rev) = indexer.reverse(idx);
 
-    assert_eq!((x, y), (x_rev, y_rev));
+	assert_eq!((x, y), (x_rev, y_rev));
 }
 
 #[test_case(5, -1)]
@@ -46,43 +49,40 @@ fn test_index_is_reflexive(x: usize, y: usize) {
 #[test_case(-12, 3)]
 #[test_case(-00, 123_000_000)]
 fn test_indexer_index_checked_returns_none_for_out_of_bounds(x: i64, y: i64) {
-    let indexer = Indexer::new(10, 10);
-    assert_eq!(indexer.index_checked(x, y), None);
+	let indexer = Indexer::new(10, 10);
+	assert_eq!(indexer.index_checked(x, y), None);
 }
 
-
 #[test]
 fn test_indexer_with_zero_dimensions() {
+	// Create an indexer with zero width
+	let zero_width_indexer = Indexer::new(0, 10);
 
-    // Create an indexer with zero width
-    let zero_width_indexer = Indexer::new(0, 10);
+	assert_eq!(zero_width_indexer.width(), 0);
+	assert_eq!(zero_width_indexer.height(), 10);
 
-    assert_eq!(zero_width_indexer.width(), 0);
-    assert_eq!(zero_width_indexer.height(), 10);
+	// Zero width should make all x coordinates invalid
+	assert!(!zero_width_indexer.is_valid(0, 5));
+	assert_eq!(zero_width_indexer.index_checked(0, 5), None);
 
-    // Zero width should make all x coordinates invalid
-    assert!(!zero_width_indexer.is_valid(0, 5));
-    assert_eq!(zero_width_indexer.index_checked(0, 5), None);
+	// Index calculation with zero width
+	assert_eq!(zero_width_indexer.index(2, 3), 0); // 3 * 0 + 2 = 0
 
-    // Index calculation with zero width
-    assert_eq!(zero_width_indexer.index(2, 3), 0); // 3 * 0 + 2 = 0
+	// Reverse calculation with zero width
+	let (x, y) = zero_width_indexer.reverse(5);
+	assert_eq!(x, 0); // Any index % 0 is treated as 0 due to .max(0)
+	assert_eq!(y, 0); // Any index / 0 is treated as 0 due to .max(0)
 
-    // Reverse calculation with zero width
-    let (x, y) = zero_width_indexer.reverse(5);
-    assert_eq!(x, 0); // Any index % 0 is treated as 0 due to .max(0)
-    assert_eq!(y, 0); // Any index / 0 is treated as 0 due to .max(0)
+	// Create an indexer with zero height
+	let zero_height_indexer = Indexer::new(10, 0);
+	assert_eq!(zero_height_indexer.width(), 10);
+	assert_eq!(zero_height_indexer.height(), 0);
 
-    // Create an indexer with zero height
-    let zero_height_indexer = Indexer::new(10, 0);
-    assert_eq!(zero_height_indexer.width(), 10);
-    assert_eq!(zero_height_indexer.height(), 0);
+	// Zero height should make all y coordinates invalid
+	assert!(!zero_height_indexer.is_valid(5, 0));
+	assert_eq!(zero_height_indexer.index_checked(5, 0), None);
 
-    // Zero height should make all y coordinates invalid
-    assert!(!zero_height_indexer.is_valid(5, 0));
-    assert_eq!(zero_height_indexer.index_checked(5, 0), None);
-
-    // Test flip_y with zero height
-    let flipped = zero_height_indexer.flip_y(IVec2::new(5, 3));
-    assert_eq!(flipped, IVec2::new(5, -3)); // 0 - 3 = -3
+	// Test flip_y with zero height
+	let flipped = zero_height_indexer.flip_y(IVec2::new(5, 3));
+	assert_eq!(flipped, IVec2::new(5, -3)); // 0 - 3 = -3
 }
-