diff --git a/Cargo.toml b/Cargo.toml
index e492e64..5d2facd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,7 +19,6 @@ members = [
 [features]
 scripting = ["dep:lyra-scripting"]
 lua_scripting = ["scripting", "lyra-scripting/lua"]
-tracy = ["lyra-game/tracy"]
 
 [dependencies]
 lyra-game = { path = "crates/lyra-game" }
diff --git a/crates/lyra-ecs/src/query/filter/has.rs b/crates/lyra-ecs/src/query/filter/has.rs
index 16eafcf..3b7f11d 100644
--- a/crates/lyra-ecs/src/query/filter/has.rs
+++ b/crates/lyra-ecs/src/query/filter/has.rs
@@ -8,25 +8,27 @@ use super::StaticFetcher;
 /// 
 /// This does not return a reference to the component, it returns `()` if the entity has
 /// the component. This query is great when its used with [`Or`](super::Or).
+/// 
+/// See [`Without`].
 #[derive(Default)]
-pub struct Has<C: Component> {
+pub struct With<C: Component> {
     _marker: PhantomData<C>
 }
 
-impl<C: Component> Copy for Has<C> {}
+impl<C: Component> Copy for With<C> {}
 
-impl<C: Component> Clone for Has<C> {
+impl<C: Component> Clone for With<C> {
     fn clone(&self) -> Self {
         Self { _marker: self._marker.clone() }
     }
 }
 
-impl<C: Component> Query for Has<C> {
+impl<C: Component> Query for With<C> {
     type Item<'a> = bool;
     type Fetch<'a> = StaticFetcher<bool>;
 
     fn new() -> Self {
-        Has {
+        With {
             _marker: PhantomData
         }
     }
@@ -41,7 +43,7 @@ impl<C: Component> Query for Has<C> {
     }
 }
 
-impl<C: Component> AsQuery for Has<C> {
+impl<C: Component> AsQuery for With<C> {
     type Query = Self;
 }
 
diff --git a/crates/lyra-ecs/src/query/filter/mod.rs b/crates/lyra-ecs/src/query/filter/mod.rs
index 8031f56..429e029 100644
--- a/crates/lyra-ecs/src/query/filter/mod.rs
+++ b/crates/lyra-ecs/src/query/filter/mod.rs
@@ -10,6 +10,9 @@ pub use not::*;
 mod changed;
 pub use changed::*;
 
+mod without;
+pub use without::*;
+
 use crate::{Archetype, ArchetypeEntityId, Tick, World};
 
 use super::{Fetch, Query};
diff --git a/crates/lyra-ecs/src/query/filter/without.rs b/crates/lyra-ecs/src/query/filter/without.rs
new file mode 100644
index 0000000..6aa7b73
--- /dev/null
+++ b/crates/lyra-ecs/src/query/filter/without.rs
@@ -0,0 +1,45 @@
+use std::marker::PhantomData;
+
+use crate::{query::{AsQuery, Query}, Archetype, Component, DynTypeId, World};
+
+use super::StaticFetcher;
+
+/// A filter query for entities that do not have the component `C`.
+/// 
+/// See [`With`].
+#[derive(Default)]
+pub struct Without<C: Component> {
+    _marker: PhantomData<C>
+}
+
+impl<C: Component> Copy for Without<C> {}
+
+impl<C: Component> Clone for Without<C> {
+    fn clone(&self) -> Self {
+        Self { _marker: self._marker.clone() }
+    }
+}
+
+impl<C: Component> Query for Without<C> {
+    type Item<'a> = bool;
+    type Fetch<'a> = StaticFetcher<bool>;
+
+    fn new() -> Self {
+        Without {
+            _marker: PhantomData
+        }
+    }
+
+    fn can_visit_archetype(&self, archetype: &Archetype) -> bool {
+        !archetype.has_column(DynTypeId::of::<C>())
+    }
+
+    unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> {
+        // if fetch is called, it means that 'can_visit_archetype' returned true
+        StaticFetcher::new(true)
+    }
+}
+
+impl<C: Component> AsQuery for Without<C> {
+    type Query = Self;
+}
diff --git a/crates/lyra-game/Cargo.toml b/crates/lyra-game/Cargo.toml
index dec0e02..4842e3c 100644
--- a/crates/lyra-game/Cargo.toml
+++ b/crates/lyra-game/Cargo.toml
@@ -17,10 +17,6 @@ winit = "0.30.5"
 wgpu = { version = "22.1.0" }
 
 tracing = "0.1.37"
-tracing-subscriber = { version = "0.3.16", features = [ "tracing-log" ] }
-tracing-log = "0.2.0"
-tracing-appender = "0.2.2"
-tracing-tracy = { version = "0.11.0", optional = true }
 
 async-std = { version = "1.12.0", features = [ "unstable", "attributes" ] }
 cfg-if = "1"
@@ -43,6 +39,3 @@ round_mult = "0.1.3"
 fast_poisson = { version = "1.0.0", features = ["single_precision"] }
 atomic_refcell = "0.1.13"
 rand = "0.8.5"
-
-[features]
-tracy = ["dep:tracing-tracy"]
diff --git a/crates/lyra-game/src/game.rs b/crates/lyra-game/src/game.rs
index 63c25a4..80d58d4 100755
--- a/crates/lyra-game/src/game.rs
+++ b/crates/lyra-game/src/game.rs
@@ -2,13 +2,7 @@ use std::{cell::OnceCell, collections::VecDeque, ptr::NonNull};
 
 use lyra_ecs::{system::{IntoSystem, System}, ResourceObject, World};
 use lyra_math::IVec2;
-use tracing::{error, info, Level};
-use tracing_appender::non_blocking;
-use tracing_subscriber::{
-    layer::SubscriberExt,
-    filter,
-    util::SubscriberInitExt, fmt,
-};
+use tracing::{error, info};
 
 use crate::{event_cleaner_system, plugin::Plugin, render::renderer::Renderer, Event, Events, Stage, StagedExecutor};
 
@@ -60,28 +54,7 @@ pub struct App {
 
 impl App {
     pub fn new() -> Self {
-        // init logging
-        let (stdout_layer, stdout_nb) = non_blocking(std::io::stdout());
-        {
-            let t = tracing_subscriber::registry()
-                .with(fmt::layer().with_writer(stdout_layer));
-
-            #[cfg(feature = "tracy")]
-            let t = t.with(tracing_tracy::TracyLayer::default());
-
-            t.with(filter::Targets::new()
-                    // done by prefix, so it includes all lyra subpackages
-                    .with_target("lyra", Level::DEBUG)
-                    .with_target("wgsl_preprocessor", Level::INFO)
-                    .with_target("wgpu", Level::WARN)
-                    .with_target("winit", Level::DEBUG)
-                    .with_default(Level::INFO))
-                .init();
-        }
-
-        // store the logger worker guard to ensure logging still happens
-        let mut world = World::new();
-        world.add_resource(stdout_nb);
+        let world = World::new();
 
         // initialize ecs system stages
         let mut staged = StagedExecutor::new();
diff --git a/crates/lyra-game/src/render/graph/passes/shadows.rs b/crates/lyra-game/src/render/graph/passes/shadows.rs
index 8d031ab..578888d 100644
--- a/crates/lyra-game/src/render/graph/passes/shadows.rs
+++ b/crates/lyra-game/src/render/graph/passes/shadows.rs
@@ -9,7 +9,7 @@ use fast_poisson::{Poisson2D, Poisson3D};
 use glam::Vec2;
 use itertools::Itertools;
 use lyra_ecs::{
-    query::{filter::Has, Entities},
+    query::{filter::With, Entities},
     AtomicRef, Component, Entity, ResourceData,
 };
 use lyra_game_derive::RenderGraphLabel;
@@ -679,7 +679,7 @@ impl Node for ShadowMapsPass {
             Entities,
             &Transform,
             Option<&ShadowCasterSettings>,
-            Has<DirectionalLight>,
+            With<DirectionalLight>,
         )>() {
             if !self.depth_maps.contains_key(&entity) {
                 let (custom_settings, shadow_settings) = shadow_settings
@@ -703,7 +703,7 @@ impl Node for ShadowMapsPass {
             Entities,
             &Transform,
             Option<&ShadowCasterSettings>,
-            Has<PointLight>,
+            With<PointLight>,
         )>() {
             if !self.depth_maps.contains_key(&entity) {
                 let (custom_settings, shadow_settings) = shadow_settings
diff --git a/crates/lyra-game/src/sprite/tilemap.rs b/crates/lyra-game/src/sprite/tilemap.rs
index fb1b75b..3834f3c 100644
--- a/crates/lyra-game/src/sprite/tilemap.rs
+++ b/crates/lyra-game/src/sprite/tilemap.rs
@@ -1,7 +1,7 @@
 use glam::{UVec2, UVec3, Vec2, Vec3};
 use lyra_ecs::{
     query::{
-        filter::{Changed, Has, Not},
+        filter::{Changed, With, Not},
         Entities, View, ViewOne,
     },
     relation::{ChildOf, RelationOriginComponent},
@@ -179,7 +179,7 @@ fn system_relative_tile_position_update(
             Option<&mut Transform>,
             Option<&WorldTransform>,
         ),
-        (Changed<TileMapPos>, Not<Has<Tile>>),
+        (Changed<TileMapPos>, Not<With<Tile>>),
     >,
     tile_map_view: ViewOne<&TileMap>,
     child_of_rel_view: ViewOne<&RelationOriginComponent<ChildOf>>,
diff --git a/crates/lyra-scene/src/lib.rs b/crates/lyra-scene/src/lib.rs
index 361c197..a6746cb 100644
--- a/crates/lyra-scene/src/lib.rs
+++ b/crates/lyra-scene/src/lib.rs
@@ -167,7 +167,7 @@ pub(crate) fn world_add_child_node<B: Bundle>(world: &mut World, parent: &SceneN
 
 #[cfg(test)]
 pub mod tests {
-    use lyra_ecs::{query::{filter::{Has, Not}, Entities}, relation::{ChildOf, RelationOriginComponent}, Component};
+    use lyra_ecs::{query::{filter::{With, Not}, Entities}, relation::{ChildOf, RelationOriginComponent}, Component};
     use lyra_math::{Transform, Vec3};
     use lyra_resource::ResHandle;
 
@@ -206,7 +206,7 @@ pub mod tests {
         let b = a.add_node(&mut scene, (WorldTransform::default(), Transform::from_translation(v2s[1]), FakeMesh));
         assert!(b.parent(&scene).unwrap() == a);
 
-        let view = scene.world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+        let view = scene.world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
         crate::system_update_world_transforms(&scene.world, view).unwrap();
 
         let mut idx = 0;
diff --git a/crates/lyra-scene/src/node.rs b/crates/lyra-scene/src/node.rs
index 267e7fb..4cdd9c4 100644
--- a/crates/lyra-scene/src/node.rs
+++ b/crates/lyra-scene/src/node.rs
@@ -61,7 +61,7 @@ impl SceneNode {
 
 #[cfg(test)]
 mod tests {
-    use lyra_ecs::{query::{filter::{Has, Not}, Entities}, relation::{ChildOf, RelationOriginComponent}};
+    use lyra_ecs::{query::{filter::{With, Not}, Entities}, relation::{ChildOf, RelationOriginComponent}};
     use lyra_math::{Transform, Vec3};
     use lyra_resource::ResHandle;
     
@@ -78,7 +78,7 @@ mod tests {
         assert!(b.parent(&scene).unwrap() == a);
 
         // update global transforms
-        let view = scene.world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+        let view = scene.world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
         crate::system_update_world_transforms(&scene.world, view).unwrap();
 
         let tran = scene.world.view_one::<&WorldTransform>(b.entity).unwrap();
diff --git a/crates/lyra-scene/src/world_transform.rs b/crates/lyra-scene/src/world_transform.rs
index 2f5fa1e..8679726 100644
--- a/crates/lyra-scene/src/world_transform.rs
+++ b/crates/lyra-scene/src/world_transform.rs
@@ -1,6 +1,6 @@
 use std::ops::Deref;
 
-use lyra_ecs::{query::{filter::{Has, Not}, Entities, View}, relation::{ChildOf, RelationOriginComponent}, Component, Entity, World};
+use lyra_ecs::{query::{filter::{With, Not}, Entities, View}, relation::{ChildOf, RelationOriginComponent}, Component, Entity, World};
 use lyra_math::Transform;
 use lyra_reflect::Reflect;
 use lyra_resource::ResHandle;
@@ -35,7 +35,7 @@ impl From<Transform> for WorldTransform {
 /// For entities without parents, this will update world transform to match local transform.
 /// For any children entities, their [`WorldTransform`]s will be updated to reflect the changes
 /// of its parent entity.
-pub fn system_update_world_transforms(world: &World, view: View<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>) -> anyhow::Result<()> {    
+pub fn system_update_world_transforms(world: &World, view: View<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>) -> anyhow::Result<()> {    
     for (en, mut world_tran, tran, scene) in view.into_iter() {
         world_tran.0 = *tran;
         recurse_update_trans(world, &world_tran, en)?;
@@ -44,7 +44,7 @@ pub fn system_update_world_transforms(world: &World, view: View<(Entities, &mut
         if let Some(scene) = scene {
             if let Some(scene) = scene.data_ref() {
                 let sworld = &scene.world;
-                let view = sworld.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+                let view = sworld.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
                 system_update_world_transforms(&scene.world, view)?;
             }
         }
@@ -72,7 +72,7 @@ fn recurse_update_trans(world: &World, parent_transform: &WorldTransform, entity
         if let Some(scene) = scene {
             if let Some(scene) = scene.data_ref() {
                 let sworld = &scene.world;
-                let view = sworld.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+                let view = sworld.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
                 system_update_world_transforms(&scene.world, view)?;
             }
         }
@@ -87,7 +87,7 @@ fn recurse_update_trans(world: &World, parent_transform: &WorldTransform, entity
 
 #[cfg(test)]
 mod tests {
-    use lyra_ecs::{query::{filter::{Has, Not}, Entities}, relation::{ChildOf, RelationOriginComponent}, World};
+    use lyra_ecs::{query::{filter::{With, Not}, Entities}, relation::{ChildOf, RelationOriginComponent}, World};
     use lyra_math::Transform;
     use lyra_resource::ResHandle;
 
@@ -101,7 +101,7 @@ mod tests {
         let child = world.spawn((WorldTransform::default(), Transform::from_xyz(15.0, 15.0, 15.0)));
         world.add_relation(child, ChildOf, parent);
 
-        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
         system_update_world_transforms(&world, view).unwrap();
 
         let g = world.view_one::<&WorldTransform>(child).unwrap();
@@ -126,7 +126,7 @@ mod tests {
         let second_child = world.spawn((WorldTransform::default(), Transform::from_xyz(5.0, 3.0, 8.0)));
         world.add_relation(second_child, ChildOf, parent);
 
-        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
         system_update_world_transforms(&world, view).unwrap();
 
         let mut base_offset = 25.0;
@@ -159,7 +159,7 @@ mod tests {
         let five_child = world.spawn((WorldTransform::default(), Transform::from_xyz(356.0, 54.0, 786.0)));
         world.add_relation(five_child, ChildOf, four_child);
 
-        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
         system_update_world_transforms(&world, view).unwrap();
 
         let g = world.view_one::<&WorldTransform>(five_child).unwrap();
@@ -186,7 +186,7 @@ mod tests {
         let five_child = world.spawn((WorldTransform::default(), Transform::from_xyz(356.0, 54.0, 786.0)));
         world.add_relation(five_child, ChildOf, sec_chi);
 
-        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<Has<RelationOriginComponent<ChildOf>>>>();
+        let view = world.filtered_view::<(Entities, &mut WorldTransform, &Transform, Option<&ResHandle<SceneGraph>>), Not<With<RelationOriginComponent<ChildOf>>>>();
         system_update_world_transforms(&world, view).unwrap();
 
         let g = world.view_one::<&WorldTransform>(five_child).unwrap();