kitgit

tirbofish/dropbear · commit

3f051349767f0feb3499c0f75baa5218af11aa72

Merge pull request #47 from 4tkbytes/big-refactor fix: remove a threadsafe world, instead make it singlethreaded and add async jobs for model loading.

Unverified

tk <4tkbytes@pm.me> · 2025-09-24 04:51

view full diff

diff --git a/.gitignore b/.gitignore
index 889428d..f5ab93d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,8 @@ dropbear-engine/src/resources/textures/Autism.png
 .vscode
 docs
 
+dropbear_future-queue/test.log
+
 # gleam
 *.beam
 *.ez
diff --git a/Cargo.toml b/Cargo.toml
index c7145dd..d9cb2f4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,11 +2,11 @@
 package.version = "0.1.2"
 package.edition = "2024"
 package.license-file = "LICENSE.md"
-package.repository = "https://github.com/4tkbytes/dropbear-engine"
+package.repository = "https://github.com/4tkbytes/dropbear"
 package.readme = "README.md"
 
 resolver = "3"
-members = [ "dropbear-engine", "eucalyptus-core", "eucalyptus-editor"]
+members = [ "dropbear-engine", "dropbear_future-queue", "eucalyptus-core", "eucalyptus-editor"]
 # members = ["dropbear-engine", "eucalyptus-core", "eucalyptus-editor", "redback-runtime"]
 
 
diff --git a/README.md b/README.md
index 503cc27..244de31 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ If you might have not realised, all the crates/projects names are after Australi
 - [redback-runtime](https://github.com/4tkbytes/redback-runtime) is the runtime used to load .eupak files and run the games loaded on them.
 
 ### Related Projects
-
+- [dropbear_future-queue](https://github.com/4tkbytes/dropbear/tree/main/dropbear_future-queue) is a handy library for dealing with async in a sync context
 - [model_to_image](https://github.com/4tkbytes/model_to_image) is a library used to generate thumbnails and images from a 3D model with the help of `russimp-ng`
 
 ## Build
@@ -54,21 +54,14 @@ If you do not want to build it locally, you are able to download the latest acti
 
 ## Usage
 
-~~Depsite it looking like a dependency for `eucalyptus`, it can serve as a framework too. Looking through the `docs.rs` will you find related documentation onhow to use it and for rendering your own projects.~~
-
-dropbear cannot be used as a framework (yet), but is best compatible with the eucalyptus editor when making games. For 
-scripting, eucalyptus uses `typescript`. The main philosophy of scripting is to be able to have **type safety**, which can aid developers with their code, which is the reason as to why I didn't use `javascript` for scripting instead.
-
-The typescript used in the scripting is ran with the deno runtime. 
-
-Documentation is hosted on GitHub Pages with typedoc. The website is at this link: [4tkbytes.github.io/dropbear][https://4tkbytes.github.io/dropbear/]
+todo
 
 ## Compability
 
-|            | Windows | macOS | Linux | Web | Android | iOS |
-|------------|---------|-------|-------|-----|---------|-----|
-| eucalyptus |    ✅    |   ✅   |   ✅   |  ❌<sup>1</sup>  |    ❌<sup>1</sup>    |  ❌<sup>1</sup>  |
-| redback    |    ✅    |   ✅   |   ✅   |  ❌<sup>2</sup>  |    ❌<sup>2</sup>    |  ❌  |
+|            | Windows | macOS | Linux | Web           | Android       | iOS           |
+|------------|---------|-------|-------|---------------|---------------|---------------|
+| eucalyptus | ✅       | ✅     | ✅     | ❌<sup>1</sup> | ❌<sup>1</sup> | ❌<sup>1</sup> |
+| redback    | ✅       | ✅     | ✅     | ❌<sup>2</sup> | ❌<sup>2</sup> | ❌             |
 
 <sup>1</sup> Will never be implemented; not intended for that platform.
 
diff --git a/dropbear-engine/Cargo.toml b/dropbear-engine/Cargo.toml
index 9324376..7710e9b 100644
--- a/dropbear-engine/Cargo.toml
+++ b/dropbear-engine/Cargo.toml
@@ -9,6 +9,7 @@ repository.workspace = true
 readme.workspace = true
 
 [dependencies]
+dropbear_future-queue = { path = "../dropbear_future-queue" }
 anyhow.workspace = true
 app_dirs2.workspace = true
 bytemuck.workspace = true
@@ -32,8 +33,6 @@ parking_lot.workspace = true
 lazy_static.workspace = true
 gltf.workspace = true
 rayon.workspace = true
-tokio.workspace = true
-async-trait.workspace = true
 backtrace.workspace = true
 os_info.workspace = true
 rustc_version_runtime.workspace = true
@@ -42,8 +41,8 @@ rustc_version_runtime.workspace = true
 rfd.workspace = true
 arboard.workspace = true
 
-[target.'cfg(target_os = "android")'.dependencies]
-android_logger = "0.15"
+# [target.'cfg(target_os = "android")'.dependencies]
+# android_logger = "0.15"
 
 [dependencies.image]
 version = "0.25"
diff --git a/dropbear-engine/src/attenuation.rs b/dropbear-engine/src/attenuation.rs
index 2dbb539..a65230a 100644
--- a/dropbear-engine/src/attenuation.rs
+++ b/dropbear-engine/src/attenuation.rs
@@ -1,3 +1,7 @@
+//! The attenuation values of light.
+//!
+//! See https://en.wikipedia.org/wiki/Attenuation
+
 #[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
 pub struct Attenuation {
     pub range: f32,
diff --git a/dropbear-engine/src/buffer.rs b/dropbear-engine/src/buffer.rs
index e89e3d1..59ab6a5 100644
--- a/dropbear-engine/src/buffer.rs
+++ b/dropbear-engine/src/buffer.rs
@@ -1,3 +1,5 @@
+//! Vertices and different buffers used for wgpu
+
 #[repr(C)]
 #[derive(Copy, Clone, Debug, Default, bytemuck::Pod, bytemuck::Zeroable)]
 pub struct Vertex {
diff --git a/dropbear-engine/src/camera.rs b/dropbear-engine/src/camera.rs
index a4060ab..8e518e2 100644
--- a/dropbear-engine/src/camera.rs
+++ b/dropbear-engine/src/camera.rs
@@ -1,3 +1,5 @@
+//! Camera and components related to cameras. 
+
 use std::sync::Arc;
 
 use glam::{DMat4, DQuat, DVec3, Mat4};
@@ -8,6 +10,7 @@ use wgpu::{
 
 use crate::graphics::SharedGraphicsContext;
 
+/// Matrix that converts OpenGL (from [`glam`]) to [`wgpu`] values
 #[rustfmt::skip]
 pub const OPENGL_TO_WGPU_MATRIX: [[f64; 4]; 4] = [
     [1.0, 0.0, 0.0, 0.0],
@@ -16,65 +19,86 @@ pub const OPENGL_TO_WGPU_MATRIX: [[f64; 4]; 4] = [
     [0.0, 0.0, 0.5, 1.0],
 ];
 
+/// The basic values of a Camera.
 #[derive(Default, Debug, Clone)]
 pub struct Camera {
+    /// The name of the camera
     pub label: String,
 
+    /// Eye of camera / Position
     pub eye: DVec3,
+    /// Target of camera / Looking at
     pub target: DVec3,
+    /// Up
     pub up: DVec3,
+    /// Aspect ratio
     pub aspect: f64,
+    /// FOV of camera
     pub fov_y: f64,
+    /// Near buffer?
     pub znear: f64,
+    /// Far buffer?
     pub zfar: f64,
+    /// Yaw (rotation)
     pub yaw: f64,
+    /// Pitch (rotation)
     pub pitch: f64,
 
+    /// Uniform/interface for Rust and the GPU
     pub uniform: CameraUniform,
     buffer: Option<Buffer>,
 
     layout: Option<BindGroupLayout>,
     bind_group: Option<BindGroup>,
 
+    /// Speed of the camera
     pub speed: f64,
+    /// Sensitivity of the mouse for the camera
     pub sensitivity: f64,
 
+    /// View matrix
     pub view_mat: DMat4,
+    /// Projection Matrix
     pub proj_mat: DMat4,
 }
 
+/// A simple builder/struct that allows you to build a [`Camera`]
+pub struct CameraBuilder {
+    pub eye: DVec3,
+    pub target: DVec3,
+    pub up: DVec3,
+    pub aspect: f64,
+    pub fov_y: f64,
+    pub znear: f64,
+    pub zfar: f64,
+    pub speed: f64,
+    pub sensitivity: f64,
+}
+
 impl Camera {
     /// Creates a new camera
     pub fn new(
         graphics: Arc<SharedGraphicsContext>,
-        eye: DVec3,
-        target: DVec3,
-        up: DVec3,
-        aspect: f64,
-        fov_y: f64,
-        znear: f64,
-        zfar: f64,
-        speed: f64,
-        sensitivity: f64,
+        builder: CameraBuilder,
         label: Option<&str>,
     ) -> Self {
         let uniform = CameraUniform::new();
         let mut camera = Self {
-            eye,
-            target,
-            up,
-            aspect,
-            fov_y,
-            znear,
-            zfar,
+            eye: builder.eye,
+            target: builder.target,
+            up: builder.up,
+            aspect: builder.aspect,
+            fov_y: builder.fov_y,
+            znear: builder.znear,
+            zfar: builder.zfar,
             uniform,
             buffer: None,
             layout: None,
             bind_group: None,
-            speed,
+            speed: builder.speed,
             yaw: 0.0,
             pitch: 0.0,
-            sensitivity,
+            sensitivity: builder.sensitivity,
             label: if let Some(l) = label {
                 l.to_string()
             } else {
@@ -94,19 +118,21 @@ impl Camera {
     pub fn predetermined(graphics: Arc<SharedGraphicsContext>, label: Option<&str>) -> Self {
         Self::new(
             graphics.clone(),
-            DVec3::new(0.0, 1.0, 2.0),
-            DVec3::new(0.0, 0.0, 0.0),
-            DVec3::Y,
-            (graphics.screen_size.0 / graphics.screen_size.1).into(),
-            45.0,
-            0.1,
-            100.0,
-            1.0,
-            0.002,
+            CameraBuilder {
+                eye: DVec3::new(0.0, 1.0, 2.0),
+                target: DVec3::new(0.0, 0.0, 0.0),
+                up: DVec3::Y,
+                aspect: (graphics.screen_size.0 / graphics.screen_size.1).into(),
+                fov_y: 45.0,
+                znear: 0.1,
+                zfar: 100.0,
+                speed: 1.0,
+                sensitivity: 0.002,
+            },
             label,
         )
     }
-
+    
     pub fn rotation(&self) -> DQuat {
         let yaw = DQuat::from_axis_angle(DVec3::Y, self.yaw);
         let pitch = DQuat::from_axis_angle(DVec3::X, self.pitch);
@@ -133,6 +159,7 @@ impl Camera {
         self.eye
     }
 
+    /// Prints out the values of the camera. 
     pub fn debug_camera_state(&self) {
         let camera = self;
         log::debug!("Camera state:");
@@ -154,11 +181,10 @@ impl Camera {
             self.znear,
         );
 
-        self.view_mat = view.clone();
-        self.proj_mat = proj.clone();
+        self.view_mat = view;
+        self.proj_mat = proj;
 
-        let result = DMat4::from_cols_array_2d(&OPENGL_TO_WGPU_MATRIX) * proj * view;
-        result
+        DMat4::from_cols_array_2d(&OPENGL_TO_WGPU_MATRIX) * proj * view
     }
 
     pub fn create_bind_group_layout(
@@ -198,7 +224,7 @@ impl Camera {
     pub fn update(&mut self, graphics: Arc<SharedGraphicsContext>) {
         self.update_view_proj();
         graphics.queue.write_buffer(
-            &self.buffer.as_ref().unwrap(),
+            self.buffer.as_ref().unwrap(),
             0,
             bytemuck::cast_slice(&[self.uniform]),
         );
diff --git a/dropbear-engine/src/entity.rs b/dropbear-engine/src/entity.rs
index 28792e8..07efd38 100644
--- a/dropbear-engine/src/entity.rs
+++ b/dropbear-engine/src/entity.rs
@@ -87,7 +87,7 @@ pub struct LazyAdoptedEntity {
 impl LazyAdoptedEntity {
     /// Create a LazyAdoptedEntity from a file path (can be run on background thread)
     pub async fn from_file(path: &PathBuf, label: Option<&str>) -> anyhow::Result<Self> {
-        let buffer = tokio::fs::read(path).await?;
+        let buffer = std::fs::read(path)?;
         Self::from_memory(buffer, label).await
     }
 
@@ -141,7 +141,7 @@ impl AdoptedEntity {
         label: Option<&str>,
     ) -> anyhow::Result<Self> {
         let path = path.as_ref().to_path_buf();
-        let model = Model::load(graphics.clone(), &path, label.clone()).await?;
+        let model = Model::load(graphics.clone(), &path, label).await?;
         Ok(Self::adopt(graphics, model).await)
     }
 
diff --git a/dropbear-engine/src/graphics.rs b/dropbear-engine/src/graphics.rs
index d42ceab..db1b2de 100644
--- a/dropbear-engine/src/graphics.rs
+++ b/dropbear-engine/src/graphics.rs
@@ -14,15 +14,15 @@ use wgpu::{
     util::{BufferInitDescriptor, DeviceExt},
 };
 use winit::window::Window;
-
+use dropbear_future_queue::FutureQueue;
 use crate::{
     State,
     egui_renderer::EguiRenderer,
     model::{self, Vertex},
 };
 
-pub const NO_TEXTURE: &'static [u8] = include_bytes!("../../resources/no-texture.png");
-pub const NO_MODEL: &'static [u8] = include_bytes!("../../resources/error.glb");
+pub const NO_TEXTURE: &[u8] = include_bytes!("../../resources/no-texture.png");
+pub const NO_MODEL: &[u8] = include_bytes!("../../resources/error.glb");
 
 pub struct RenderContext<'a> {
     pub shared: Arc<SharedGraphicsContext>,
@@ -40,6 +40,7 @@ pub struct SharedGraphicsContext {
     pub diffuse_sampler: Arc<Sampler>,
     pub screen_size: (f32, f32),
     pub texture_id: Arc<TextureId>,
+    pub future_queue: Arc<FutureQueue>,
 }
 
 pub struct FrameGraphicsContext<'a> {
@@ -101,6 +102,7 @@ impl<'a> RenderContext<'a> {
         }));
         Self {
             shared: Arc::new(SharedGraphicsContext {
+                future_queue: state.future_queue.clone(),
                 device: state.device.clone(),
                 queue: state.queue.clone(),
                 instance: Arc::new(state.instance.clone()),
@@ -193,7 +195,7 @@ impl<'a> RenderContext<'a> {
             .begin_render_pass(&wgpu::RenderPassDescriptor {
                 label: Some("Render Pass"),
                 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
-                    view: &self.frame.view,
+                    view: self.frame.view,
                     resolve_target: None,
                     ops: wgpu::Operations {
                         load: wgpu::LoadOp::Clear(color),
@@ -220,7 +222,7 @@ impl<'a> RenderContext<'a> {
             .begin_render_pass(&wgpu::RenderPassDescriptor {
                 label: Some("Render Pass"),
                 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
-                    view: &self.frame.view,
+                    view: self.frame.view,
                     resolve_target: None,
                     ops: wgpu::Operations {
                         load: wgpu::LoadOp::Load,
@@ -400,7 +402,7 @@ impl Texture {
         };
 
         let desc = TextureDescriptor {
-            label: label,
+            label,
             size,
             mip_level_count: 1,
             sample_count: 1,
diff --git a/dropbear-engine/src/input.rs b/dropbear-engine/src/input.rs
index cea334c..6fd9d93 100644
--- a/dropbear-engine/src/input.rs
+++ b/dropbear-engine/src/input.rs
@@ -1,6 +1,6 @@
 use gilrs::{Axis, EventType, Gilrs};
+use parking_lot::RwLock;
 use std::{
-    cell::RefCell,
     collections::{HashMap, HashSet},
     rc::Rc,
 };
@@ -8,9 +8,9 @@ use winit::{
     dpi::PhysicalPosition, event::MouseButton, event_loop::ActiveEventLoop, keyboard::KeyCode,
 };
 
-pub type KeyboardImpl = Rc<RefCell<dyn Keyboard>>;
-pub type MouseImpl = Rc<RefCell<dyn Mouse>>;
-pub type ControllerImpl = Rc<RefCell<dyn Controller>>;
+pub type KeyboardImpl = Rc<RwLock<dyn Keyboard>>;
+pub type MouseImpl = Rc<RwLock<dyn Mouse>>;
+pub type ControllerImpl = Rc<RwLock<dyn Controller>>;
 
 pub trait Keyboard {
     fn key_down(&mut self, key: KeyCode, event_loop: &ActiveEventLoop);
@@ -51,6 +51,12 @@ pub struct Manager {
     active_handlers: HashSet<String>,
 }
 
+impl Default for Manager {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl Manager {
     pub fn new() -> Self {
         Self {
@@ -89,7 +95,7 @@ impl Manager {
                 self.just_pressed_keys.insert(key);
                 for (name, handler) in self.keyboard_handlers.iter_mut() {
                     if self.active_handlers.contains(name) {
-                        handler.borrow_mut().key_down(key, event_loop);
+                        handler.write().key_down(key, event_loop);
                     }
                 }
             }
@@ -99,7 +105,7 @@ impl Manager {
                 self.just_released_keys.insert(key);
                 for (name, handler) in self.keyboard_handlers.iter_mut() {
                     if self.active_handlers.contains(name) {
-                        handler.borrow_mut().key_up(key, event_loop);
+                        handler.write().key_up(key, event_loop);
                     }
                 }
             }
@@ -113,7 +119,7 @@ impl Manager {
                 self.just_pressed_mouse_buttons.insert(button);
                 for (name, handler) in self.mouse_handlers.iter_mut() {
                     if self.active_handlers.contains(name) {
-                        handler.borrow_mut().mouse_down(button);
+                        handler.write().mouse_down(button);
                     }
                 }
             }
@@ -123,7 +129,7 @@ impl Manager {
                 self.just_released_mouse_buttons.insert(button);
                 for (name, handler) in self.mouse_handlers.iter_mut() {
                     if self.active_handlers.contains(name) {
-                        handler.borrow_mut().mouse_up(button);
+                        handler.write().mouse_up(button);
                     }
                 }
             }
@@ -135,7 +141,7 @@ impl Manager {
         self.mouse_position = position;
         for (name, handler) in self.mouse_handlers.iter_mut() {
             if self.active_handlers.contains(name) {
-                handler.borrow_mut().mouse_move(position);
+                handler.write().mouse_move(position);
             }
         }
     }
@@ -185,28 +191,28 @@ impl Manager {
             if self.active_handlers.contains(name) {
                 match event.event {
                     EventType::ButtonPressed(button, _) => {
-                        handler.borrow_mut().button_down(button, event.id);
+                        handler.write().button_down(button, event.id);
                     }
                     EventType::ButtonReleased(button, _) => {
-                        handler.borrow_mut().button_up(button, event.id);
+                        handler.write().button_up(button, event.id);
                     }
                     EventType::AxisChanged(Axis::LeftStickX, x, _) => {
-                        handler.borrow_mut().left_stick_changed(x, 0.0, event.id);
+                        handler.write().left_stick_changed(x, 0.0, event.id);
                     }
                     EventType::AxisChanged(Axis::LeftStickY, y, _) => {
-                        handler.borrow_mut().left_stick_changed(0.0, y, event.id);
+                        handler.write().left_stick_changed(0.0, y, event.id);
                     }
                     EventType::AxisChanged(Axis::RightStickX, x, _) => {
-                        handler.borrow_mut().right_stick_changed(x, 0.0, event.id);
+                        handler.write().right_stick_changed(x, 0.0, event.id);
                     }
                     EventType::AxisChanged(Axis::RightStickY, y, _) => {
-                        handler.borrow_mut().right_stick_changed(0.0, y, event.id);
+                        handler.write().right_stick_changed(0.0, y, event.id);
                     }
                     EventType::Connected => {
-                        handler.borrow_mut().on_connect(event.id);
+                        handler.write().on_connect(event.id);
                     }
                     EventType::Disconnected => {
-                        handler.borrow_mut().on_disconnect(event.id);
+                        handler.write().on_disconnect(event.id);
                     }
                     _ => {}
                 }
@@ -214,7 +220,7 @@ impl Manager {
         }
     }
 
-    pub fn poll_controllers(&mut self, gilrs: &mut gilrs::Gilrs) {
+    pub fn poll_controllers(&mut self, gilrs: &mut Gilrs) {
         while let Some(event) = gilrs.next_event() {
             self.handle_controller_event(event);
         }
diff --git a/dropbear-engine/src/lib.rs b/dropbear-engine/src/lib.rs
index a44eda2..b128202 100644
--- a/dropbear-engine/src/lib.rs
+++ b/dropbear-engine/src/lib.rs
@@ -10,7 +10,7 @@ pub mod model;
 pub mod panic;
 pub mod resources;
 pub mod scene;
-pub mod starter;
+pub mod procedural;
 pub mod utils;
 
 use app_dirs2::{AppDataType, AppInfo};
@@ -29,8 +29,8 @@ use std::{
     fmt::{self, Display, Formatter},
     sync::Arc,
     time::{Duration, Instant, SystemTime, UNIX_EPOCH},
-    u32,
 };
+use bytemuck::Contiguous;
 use wgpu::{
     BindGroupLayout, Device, Instance, Queue, Surface, SurfaceConfiguration, SurfaceError,
     TextureFormat,
@@ -50,6 +50,8 @@ pub use gilrs;
 use log::LevelFilter;
 pub use wgpu;
 pub use winit;
+pub use dropbear_future_queue as future;
+use dropbear_future_queue::FutureQueue;
 
 /// The backend information, such as the device, queue, config, surface, renderer, window and more.
 pub struct State {
@@ -64,23 +66,24 @@ pub struct State {
     pub instance: Instance,
     pub viewport_texture: Texture,
     pub texture_id: Arc<TextureId>,
+    pub future_queue: Arc<FutureQueue>,
 
     pub window: Arc<Window>,
 }
 
 impl State {
     /// Asynchronously initialised the state and sets up the backend and surface for wgpu to render to.
-    pub async fn new(window: Arc<Window>) -> anyhow::Result<Self> {
+    pub async fn new(window: Arc<Window>, future_queue: Arc<FutureQueue>) -> anyhow::Result<Self> {
         let size = window.inner_size();
 
         // create backend
-        let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
+        let instance = Instance::new(&wgpu::InstanceDescriptor {
             backends: wgpu::Backends::PRIMARY,
             // flags: wgpu::InstanceFlags::empty(),
             ..Default::default()
         });
 
-        let surface = instance.create_surface(window.clone()).unwrap();
+        let surface = instance.create_surface(window.clone())?;
 
         let adapter = instance
             .request_adapter(&wgpu::RequestAdapterOptions {
@@ -125,7 +128,7 @@ Hardware:
     Driver Info: {}
 =======================================================
 ",
-            info.backend.to_string(),
+            info.backend,
             os_info.architecture(),
             os_info.bitness(),
             os_info.codename(),
@@ -148,7 +151,7 @@ Hardware:
             .find(|f| f.is_srgb())
             .copied()
             .unwrap_or(TextureFormat::Rgba8Unorm);
-        let config = wgpu::SurfaceConfiguration {
+        let config = SurfaceConfiguration {
             usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
             format: surface_format,
             width: size.width,
@@ -215,6 +218,7 @@ Hardware:
             egui_renderer,
             viewport_texture,
             texture_id: Arc::new(texture_id),
+            future_queue
         };
 
         Ok(result)
@@ -245,7 +249,7 @@ Hardware:
     }
 
     /// Asynchronously renders the scene and the egui renderer. I don't know what else to say.
-    async fn render(
+    fn render(
         &mut self,
         scene_manager: &mut scene::Manager,
         previous_dt: f32,
@@ -257,27 +261,27 @@ Hardware:
 
         let output = match self.surface.get_current_texture() {
             Ok(val) => val,
-            Err(e) => match e {
+            Err(e) => return match e {
                 SurfaceError::Lost => {
                     log_once::warn_once!("Surface lost, reconfiguring...");
                     self.surface.configure(&self.device, &self.config);
-                    return Ok(());
+                    Ok(())
                 }
                 SurfaceError::Outdated => {
                     log_once::warn_once!("Surface outdated, reconfiguring...");
                     self.surface.configure(&self.device, &self.config);
-                    return Ok(());
+                    Ok(())
                 }
                 SurfaceError::Timeout => {
                     log_once::warn_once!("Surface timeout, skipping frame");
-                    return Ok(());
+                    Ok(())
                 }
                 SurfaceError::OutOfMemory => {
-                    return Err(anyhow::anyhow!("Surface out of memory: {:?}", e));
+                    Err(anyhow::anyhow!("Surface out of memory: {:?}", e))
                 }
                 SurfaceError::Other => {
                     log_once::warn_once!("Surface error (Other): {:?}, skipping frame", e);
-                    return Ok(());
+                    Ok(())
                 }
             },
         };
@@ -303,9 +307,8 @@ Hardware:
         let mut graphics = graphics::RenderContext::from_state(self, viewport_view, &mut encoder);
 
         scene_manager
-            .update(previous_dt, &mut graphics, event_loop)
-            .await;
-        scene_manager.render(&mut graphics).await;
+            .update(previous_dt, &mut graphics, event_loop);
+        scene_manager.render(&mut graphics);
 
         self.egui_renderer.lock().end_frame_and_draw(
             &self.device,
@@ -346,8 +349,7 @@ Hardware:
 pub fn get_current_time_as_ns() -> u128 {
     let now = SystemTime::now();
     let duration_since_epoch = now.duration_since(UNIX_EPOCH).unwrap();
-    let timestamp_ns = duration_since_epoch.as_nanos();
-    timestamp_ns
+    duration_since_epoch.as_nanos()
 }
 
 /// A struct storing the information about the application/game that is using the engine.
@@ -371,25 +373,27 @@ pub struct App {
     target_fps: u32,
     /// The library used for polling controllers, specifically the instance of that.
     gilrs: Gilrs,
-    // /// A task pool used for background async work
-    // runtime: Runtime,
+    /// A queue that polls through futures for asynchronous functions
+    /// 
+    /// Winit doesn't use async, so this is the next best alternative. 
+    future_queue: Arc<FutureQueue>,
 }
 
 impl App {
     /// Creates a new instance of the application. It only sets the default for the struct + the
     /// window config.
-    fn new(config: WindowConfiguration) -> Self {
+    fn new(config: WindowConfiguration, future_queue: Option<Arc<FutureQueue>>) -> Self {
         let result = Self {
             state: None,
             config: config.clone(),
             scene_manager: scene::Manager::new(),
             input_manager: input::Manager::new(),
-            delta_time: (1.0 / 60.0),
+            delta_time: 1.0 / 60.0,
             next_frame_time: None,
             target_fps: config.max_fps,
             // default settings for now
             gilrs: GilrsBuilder::new().build().unwrap(),
-            // runtime,
+            future_queue: future_queue.unwrap_or_else(|| Arc::new(FutureQueue::new())),
         };
         log::debug!("Created new instance of app");
         result
@@ -397,7 +401,7 @@ impl App {
 
     /// A constant that lets you not have any fps count.
     /// It is just the max value of an unsigned 32 bit number lol.
-    pub const NO_FPS_CAP: u32 = u32::MAX;
+    pub const NO_FPS_CAP: u32 = u32::MAX_VALUE;
 
     /// Helper function that sets the target frames per second. Can be used mid game to increase FPS.
     pub fn set_target_fps(&mut self, fps: u32) {
@@ -423,17 +427,17 @@ impl App {
     /// - config: The window configuration, such as the title, and window dimensions.
     /// - app_name: A string to the app name for debugging.
     /// - setup: A closure that can initialise the first scenes, such as a menu or the game itself.
+    /// 
     /// It takes an input of a scene manager and an input manager, and expects you to return back the changed
     /// managers.
-    pub async fn run<F>(config: WindowConfiguration, app_name: &str, setup: F) -> anyhow::Result<()>
+    pub async fn run<F>(config: WindowConfiguration, app_name: &str, future_queue: Option<Arc<FutureQueue>>, setup: F) -> anyhow::Result<()>
     where
         F: FnOnce(scene::Manager, input::Manager) -> (scene::Manager, input::Manager),
     {
         let log_dir = app_dirs2::app_root(AppDataType::UserData, &config.app_info)
             .expect("Failed to get app data directory")
             .join("logs");
-        tokio::fs::create_dir_all(&log_dir)
-            .await
+        std::fs::create_dir_all(&log_dir)
             .expect("Failed to create log dir");
 
         let datetime_str = Local::now().format("%Y-%m-%d_%H-%M-%S");
@@ -521,14 +525,11 @@ impl App {
         }
         log::info!("dropbear-engine running...");
         let ad = app_dirs2::get_app_root(AppDataType::UserData, &config.app_info);
-        match ad {
-            Ok(path) => {log::info!("App data is stored at {}", path.display())},
-            Err(_) => {}
-        };
+        if let Ok(path) = ad {log::info!("App data is stored at {}", path.display())};
         log::debug!("Additional nerdy stuff: {:#?}", rustc_version_runtime::version_meta());
         let event_loop = EventLoop::with_user_event().build()?;
         log::debug!("Created new event loop");
-        let mut app = Box::new(App::new(config));
+        let mut app = Box::new(App::new(config, future_queue));
         log::debug!("Configured app with details: {}", app.config);
 
         log::debug!("Running through setup");
@@ -550,10 +551,14 @@ impl App {
 /// It is crucial to run with this macro instead of the latter is for debugging purposes (and to make life
 /// easier by not having to guess your package name if it changes).
 ///
-/// See also the docs for a further run down on the parameters of how it is run: [`App::run()`]
+/// # Parameters
+/// * config - [`WindowConfiguration`]: The configuration/settings of the window. 
+/// * queue - [`Option<Throwable<FutureQueue>>`]: An optional value for a [`FutureQueue`]
+/// * setup - [`FnOnce`]: A function that sets up all the scenes. It shouldn't be loaded
+///   but instead be set as an [`Arc<Mutex<T>>>`]. 
 macro_rules! run_app {
-    ($config:expr, $setup:expr) => {
-        $crate::App::run($config, env!("CARGO_PKG_NAME"), $setup)
+    ($config:expr, $queue:expr, $setup:expr) => {
+        $crate::App::run($config, env!("CARGO_PKG_NAME"), $queue, $setup)
     };
 }
 
@@ -576,7 +581,7 @@ impl ApplicationHandler for App {
 
         let window = Arc::new(event_loop.create_window(window_attributes).unwrap());
 
-        self.state = Some(block_on(State::new(window)).unwrap());
+        self.state = Some(block_on(State::new(window, self.future_queue.clone())).unwrap());
 
         if let Some(state) = &mut self.state {
             let size = state.window.inner_size();
@@ -609,6 +614,8 @@ impl ApplicationHandler for App {
             }
             WindowEvent::Resized(size) => state.resize(size.width, size.height),
             WindowEvent::RedrawRequested => {
+                self.future_queue.poll();
+                
                 let frame_start = Instant::now();
 
                 let active_handlers = self.scene_manager.get_active_input_handlers();
@@ -616,8 +623,7 @@ impl ApplicationHandler for App {
 
                 self.input_manager.update(&mut self.gilrs);
 
-                let render_result =
-                    block_on(state.render(&mut self.scene_manager, self.delta_time, event_loop));
+                let render_result = state.render(&mut self.scene_manager, self.delta_time, event_loop);
 
                 if let Err(e) = render_result {
                     log::error!("Render failed: {:?}", e);
@@ -640,6 +646,7 @@ impl ApplicationHandler for App {
                 }
 
                 state.window.request_redraw();
+                self.future_queue.cleanup();
             }
             WindowEvent::KeyboardInput {
                 event:
@@ -650,8 +657,8 @@ impl ApplicationHandler for App {
                     },
                 ..
             } => {
-                if code == KeyCode::F11 && key_state.is_pressed() {
-                    if let Some(state) = &self.state {
+                if code == KeyCode::F11 && key_state.is_pressed()
+                    && let Some(state) = &self.state {
                         match self.config.windowed_mode {
                             WindowedModes::Windowed(_, _) => {
                                 if state.window.fullscreen().is_some() {
@@ -686,7 +693,6 @@ impl ApplicationHandler for App {
                             }
                         }
                     }
-                }
                 self.input_manager
                     .handle_key_input(code, key_state.is_pressed(), event_loop);
             }
@@ -709,7 +715,7 @@ impl ApplicationHandler for App {
 /// The window configuration of the app/game.
 ///
 /// This struct is primitive but has purpose in the way that it sets the initial specs of the window.
-/// Thats all it does. And it can also display. But thats about it.
+/// That's all it does. And it can also display. But that's about it.
 #[derive(Debug, Clone)]
 pub struct WindowConfiguration {
     pub windowed_mode: WindowedModes,
diff --git a/dropbear-engine/src/lighting.rs b/dropbear-engine/src/lighting.rs
index 1d8e95e..65752aa 100644
--- a/dropbear-engine/src/lighting.rs
+++ b/dropbear-engine/src/lighting.rs
@@ -109,9 +109,9 @@ impl Display for LightType {
     }
 }
 
-impl Into<u32> for LightType {
-    fn into(self) -> u32 {
-        match self {
+impl From<LightType> for u32 {
+    fn from(val: LightType) -> Self {
+        match val {
             LightType::Directional => 0,
             LightType::Point => 1,
             LightType::Spot => 2,
@@ -316,8 +316,8 @@ impl Light {
         label: Option<&str>,
     ) -> anyhow::Result<LazyLight> {
         let mut result = LazyLight {
-            light_component: light_component,
-            transform: transform,
+            light_component,
+            transform,
             label: label.map(|s| s.to_string()),
             cube_lazy_model: None,
         };
@@ -334,8 +334,8 @@ impl Light {
 
     pub async fn new(
         graphics: Arc<SharedGraphicsContext>,
-        light: &LightComponent,
-        transform: &Transform,
+        light: LightComponent,
+        transform: Transform,
         label: Option<&str>,
     ) -> Self {
         let forward = DVec3::new(0.0, 0.0, -1.0);
@@ -357,14 +357,14 @@ impl Light {
         let cube_model = Arc::new(Model::load_from_memory(
             graphics.clone(),
             include_bytes!("../../resources/cube.glb").to_vec(),
-            label.clone(),
+            label,
         )
         .await
         .unwrap());
 
-        let label_str = label.clone().unwrap_or("Light").to_string();
+        let label_str = label.unwrap_or("Light").to_string();
 
-        let buffer = graphics.create_uniform(uniform, label.clone());
+        let buffer = graphics.create_uniform(uniform, label);
 
         let layout = graphics
             .device
@@ -379,7 +379,7 @@ impl Light {
                     },
                     count: None,
                 }],
-                label: label.clone(),
+                label,
             });
 
         let bind_group = graphics
@@ -390,7 +390,7 @@ impl Light {
                     binding: 0,
                     resource: buffer.as_entire_binding(),
                 }],
-                label: label.clone(),
+                label,
             });
 
         let instance = Instance::new(
@@ -462,7 +462,7 @@ impl Light {
     }
 
     pub fn buffer(&self) -> &Buffer {
-        &self.buffer.as_ref().unwrap()
+        self.buffer.as_ref().unwrap()
     }
 }
 
@@ -474,6 +474,12 @@ pub struct LightManager {
     light_array_layout: Option<BindGroupLayout>,
 }
 
+impl Default for LightManager {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl LightManager {
     pub fn new() -> Self {
         log::info!("Initialised lighting");
@@ -543,7 +549,7 @@ impl LightManager {
             }
 
             if light_component.enabled && light_index < MAX_LIGHTS {
-                light_array.lights[light_index] = light.uniform().clone();
+                light_array.lights[light_index] = *light.uniform();
                 light_index += 1;
             }
         }
@@ -576,13 +582,13 @@ impl LightManager {
     ) {
         use crate::graphics::Shader;
 
-        let shader = Shader::new(graphics.clone(), shader_contents, label.clone());
+        let shader = Shader::new(graphics.clone(), shader_contents, label);
 
         let pipeline = Self::create_render_pipeline_for_lighting(
             graphics,
             &shader,
             vec![camera.layout(), self.light_array_layout.as_ref().unwrap()],
-            label.clone(),
+            label,
         );
 
         self.pipeline = Some(pipeline);
diff --git a/dropbear-engine/src/model.rs b/dropbear-engine/src/model.rs
index c8689f6..b86897a 100644
--- a/dropbear-engine/src/model.rs
+++ b/dropbear-engine/src/model.rs
@@ -16,7 +16,7 @@ use std::{mem, ops::Range, path::PathBuf};
 use std::hash::{DefaultHasher, Hash, Hasher};
 use wgpu::{BufferAddress, VertexAttribute, VertexBufferLayout, util::DeviceExt};
 
-pub const GREY_TEXTURE_BYTES: &'static [u8] = include_bytes!("../../resources/grey.png");
+pub const GREY_TEXTURE_BYTES: &[u8] = include_bytes!("../../resources/grey.png");
 
 lazy_static! {
     pub static ref MODEL_CACHE: Mutex<HashMap<String, Model>> = Mutex::new(HashMap::new());
@@ -87,7 +87,7 @@ pub trait LazyType {
     /// This can be ran after the initial thread loading is completed.
     /// # Parameters
     /// * [`Arc<SharedGraphicsContext>`] - The graphics context. It can be shared between threads
-    /// if required.
+    ///   if required.
     ///
     /// # Returns
     /// * [`Self::T`] - The data type of the item
@@ -366,7 +366,7 @@ impl Model {
             return Ok(cached_model.clone());
         }
 
-        println!(
+        log::trace!(
             "========== Benchmarking speed of loading {:?} ==========",
             label
         );
@@ -416,18 +416,18 @@ impl Model {
 
                 let load_start = Instant::now();
                 let diffuse_image = image::load_from_memory(&image_data).unwrap();
-                println!("Loading image to memory: {:?}", load_start.elapsed());
+                log::trace!("Loading image to memory: {:?}", load_start.elapsed());
 
                 let rgba_start = Instant::now();
                 let diffuse_rgba = diffuse_image.to_rgba8();
-                println!(
+                log::trace!(
                     "Converting diffuse image to rgba8 took {:?}",
                     rgba_start.elapsed()
                 );
 
                 let dimensions = diffuse_image.dimensions();
 
-                println!(
+                log::trace!(
                     "Parallel processing of material '{}' took: {:?}",
                     material_name,
                     material_start.elapsed()
@@ -437,7 +437,7 @@ impl Model {
             })
             .collect();
 
-        println!(
+        log::trace!(
             "Total parallel image processing took: {:?}",
             parallel_start.elapsed()
         );
@@ -456,7 +456,7 @@ impl Model {
                 bind_group,
             });
 
-            println!("Time to create GPU texture: {:?}", start.elapsed());
+            log::trace!("Time to create GPU texture: {:?}", start.elapsed());
         }
 
         for mesh in gltf.meshes() {
@@ -542,10 +542,10 @@ impl Model {
         };
 
         MODEL_CACHE.lock().insert(cache_key, model.clone());
-        println!("==================== DONE ====================");
+        log::trace!("==================== DONE ====================");
         log::debug!("Model cached from memory: {:?}", label);
         log::debug!("Took {:?} to load model: {:?}", start.elapsed(), label);
-        println!("==============================================");
+        log::trace!("==============================================");
         Ok(model)
     }
 
@@ -559,12 +559,16 @@ impl Model {
 
         let path_str = path.to_string_lossy().to_string();
 
+        log::debug!("Checking if model exists in cache");
         if let Some(cached_model) = MODEL_CACHE.lock().get(&path_str) {
             log::debug!("Model loaded from cache: {:?}", path_str);
             return Ok(cached_model.clone());
         }
+        log::debug!("Model does not exist in cache, loading memory...");
 
-        let buffer = tokio::fs::read(path).await?;
+        log::debug!("Path of model: {}", path.display());
+
+        let buffer = std::fs::read(path)?;
         let model = Self::load_from_memory(graphics, buffer, label).await?;
 
         MODEL_CACHE.lock().insert(path_str, model.clone());
diff --git a/dropbear-engine/src/procedural/mod.rs b/dropbear-engine/src/procedural/mod.rs
new file mode 100644
index 0000000..0c43ee9
--- /dev/null
+++ b/dropbear-engine/src/procedural/mod.rs
@@ -0,0 +1,4 @@
+//! Starter objects like planes and primitive objects are that made during runtime with
+//! vertices rather than from a model. 
+
+pub mod plane;
diff --git a/dropbear-engine/src/procedural/plane.rs b/dropbear-engine/src/procedural/plane.rs
new file mode 100644
index 0000000..f9e5094
--- /dev/null
+++ b/dropbear-engine/src/procedural/plane.rs
@@ -0,0 +1,272 @@
+use std::hash::{DefaultHasher, Hash, Hasher};
+use crate::entity::AdoptedEntity;
+use crate::graphics::{SharedGraphicsContext, Texture};
+use crate::model::{LazyType, Material, Mesh, Model, ModelId, ModelVertex, MODEL_CACHE};
+use crate::utils::{ResourceReference, ResourceReferenceType};
+use futures::executor::block_on;
+use image::GenericImageView;
+/// A straight plane (and some components). Thats it.
+///
+/// Inspiration taken from `https://github.com/4tkbytes/RedLight/blob/main/src/RedLight/Entities/Plane.cs`,
+/// my old game engine made in C sharp, where this is the plane "algorithm".
+use std::sync::Arc;
+use wgpu::{AddressMode, util::DeviceExt};
+
+/// Lazily creates a new Plane. This can only be accessed through the Default trait (which you shouldn't use),
+/// or the [`PlaneBuilder::lazy_build()`] (also taken from [`PlaneBuilder::new()`]).
+#[derive(Default)]
+pub struct LazyPlaneBuilder {
+    rgba_data: Vec<u8>,
+    dimensions: (u32, u32),
+    width: f32,
+    height: f32,
+    tiles_x: u32,
+    tiles_z: u32,
+    label: Option<String>,
+}
+
+impl LazyType for LazyPlaneBuilder {
+    type T = AdoptedEntity;
+
+    fn poke(self, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::T> {
+        let mut hasher = DefaultHasher::new();
+
+        let mut vertices = Vec::new();
+        let mut indices = Vec::new();
+
+        for z in 0..=1 {
+            for x in 0..=1 {
+                let position = [
+                    (x as f32 - 0.5) * self.width,
+                    0.0,
+                    (z as f32 - 0.5) * self.height,
+                ];
+                let normal = [0.0, 1.0, 0.0];
+                let tex_coords = [
+                    x as f32 * self.tiles_x as f32,
+                    z as f32 * self.tiles_z as f32,
+                ];
+
+                let _ = position.iter().map(|v| (*v as i32).hash(&mut hasher));
+                let _ = normal.iter().map(|v| (*v as i32).hash(&mut hasher));
+                let _ = tex_coords.iter().map(|v| (*v as i32).hash(&mut hasher));
+
+                vertices.push(ModelVertex {
+                    position,
+                    tex_coords,
+                    normal,
+                });
+            }
+        }
+
+        indices.extend_from_slice(&[0, 2, 1, 1, 2, 3]);
+        indices.hash(&mut hasher);
+
+        let vertex_buffer = graphics
+            .device
+            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: Some(&format!("{:?} Vertex Buffer", self.label.as_deref())),
+                contents: bytemuck::cast_slice(&vertices),
+                usage: wgpu::BufferUsages::VERTEX,
+            });
+        let index_buffer = graphics
+            .device
+            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: Some(&format!("{:?} Index Buffer", self.label.as_deref())),
+                contents: bytemuck::cast_slice(&indices),
+                usage: wgpu::BufferUsages::INDEX,
+            });
+
+        let mesh = Mesh {
+            name: "plane".to_string(),
+            vertex_buffer,
+            index_buffer,
+            num_elements: indices.len() as u32,
+            material: 0,
+        };
+
+        let diffuse_texture = Texture::new_with_sampler_with_rgba_buffer(
+            graphics.clone(),
+            &self.rgba_data,
+            self.dimensions,
+            AddressMode::Repeat,
+        );
+        let bind_group = diffuse_texture.bind_group().clone();
+        let material = Material {
+            name: "plane_material".to_string(),
+            diffuse_texture,
+            bind_group,
+        };
+
+        let model = Model {
+            label: self.label.as_deref().unwrap_or("Plane").to_string(),
+            path: ResourceReference::from_reference(ResourceReferenceType::Plane),
+            meshes: vec![mesh],
+            materials: vec![material],
+            id: ModelId(hasher.finish())
+        };
+
+        Ok(block_on(AdoptedEntity::adopt(graphics, model)))
+    }
+}
+
+/// Creates a plane in the form of an AdoptedEntity.
+pub struct PlaneBuilder {
+    width: f32,
+    height: f32,
+    tiles_x: u32,
+    tiles_z: u32,
+}
+
+impl Default for PlaneBuilder {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl PlaneBuilder {
+    pub fn new() -> Self {
+        Self {
+            width: 10.0,
+            height: 10.0,
+            tiles_x: 0,
+            tiles_z: 0,
+        }
+    }
+
+    pub fn with_size(mut self, width: f32, height: f32) -> Self {
+        self.width = width;
+        self.height = height;
+        self
+    }
+
+    pub fn with_tiles(mut self, tiles_x: u32, tiles_z: u32) -> Self {
+        self.tiles_x = tiles_x;
+        self.tiles_z = tiles_z;
+        self
+    }
+
+    pub async fn lazy_build(
+        mut self,
+        texture_bytes: &[u8],
+        label: Option<&str>,
+    ) -> anyhow::Result<LazyPlaneBuilder> {
+        if self.tiles_x == 0 && self.tiles_z == 0 {
+            self.tiles_x = self.width as u32;
+            self.tiles_z = self.height as u32;
+        }
+
+        let img = image::load_from_memory(texture_bytes)?;
+        let rgba = img.to_rgba8();
+        let dimensions = img.dimensions();
+
+        Ok(LazyPlaneBuilder {
+            rgba_data: rgba.into_raw(),
+            dimensions,
+            width: self.width,
+            height: self.height,
+            tiles_x: self.tiles_x,
+            tiles_z: self.tiles_z,
+            label: label.map(|s| s.to_string()),
+        })
+    }
+
+    pub async fn build(
+        mut self,
+        graphics: Arc<SharedGraphicsContext>,
+        texture_bytes: &[u8],
+        label: Option<&str>,
+    ) -> anyhow::Result<AdoptedEntity> {
+        let label = if let Some(label) = label {label.to_string()} else {format!("{}*{}_tx{}xtz{}_plane", self.width, self.height, self.tiles_x, self.tiles_z)};
+        let mut hasher = DefaultHasher::new();
+        if self.tiles_x == 0 && self.tiles_z == 0 {
+            self.tiles_x = self.width as u32;
+            self.tiles_z = self.height as u32;
+        }
+        let mut vertices = Vec::new();
+        let mut indices = Vec::new();
+
+        for z in 0..=1 {
+            for x in 0..=1 {
+                let position = [
+                    (x as f32 - 0.5) * self.width,
+                    0.0,
+                    (z as f32 - 0.5) * self.height,
+                ];
+                let normal = [0.0, 1.0, 0.0];
+                let tex_coords = [
+                    x as f32 * self.tiles_x as f32,
+                    z as f32 * self.tiles_z as f32,
+                ];
+                let _ = position.iter().map(|v| (*v as i32).hash(&mut hasher));
+                let _ = normal.iter().map(|v| (*v as i32).hash(&mut hasher));
+                let _ = tex_coords.iter().map(|v| (*v as i32).hash(&mut hasher));
+
+                vertices.push(ModelVertex {
+                    position,
+                    tex_coords,
+                    normal,
+                });
+            }
+        }
+
+        indices.extend_from_slice(&[0, 2, 1, 1, 2, 3]);
+        indices.hash(&mut hasher);
+
+        let hash = hasher.finish();
+
+        let model = if let Some(cached_model) = MODEL_CACHE.lock().get(&label.clone()) {
+            log::debug!("Model loaded from cache: {:?}", label.clone());
+            Some(cached_model.clone())
+        } else {None};
+
+        let vertex_buffer = graphics
+            .device
+            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: Some(&format!("{:?} Vertex Buffer", label.clone())),
+                contents: bytemuck::cast_slice(&vertices),
+                usage: wgpu::BufferUsages::VERTEX,
+            });
+        let index_buffer = graphics
+            .device
+            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
+                label: Some(&format!("{:?} Index Buffer", label)),
+                contents: bytemuck::cast_slice(&indices),
+                usage: wgpu::BufferUsages::INDEX,
+            });
+
+        let mesh = Mesh {
+            name: "plane".to_string(),
+            vertex_buffer,
+            index_buffer,
+            num_elements: indices.len() as u32,
+            material: 0,
+        };
+
+        let diffuse_texture =
+            Texture::new_with_sampler(graphics.clone(), texture_bytes, AddressMode::Repeat);
+        let bind_group = diffuse_texture.bind_group().clone();
+        let material = Material {
+            name: "plane_material".to_string(),
+            diffuse_texture,
+            bind_group,
+        };
+
+        let model = if let Some(m) = model {
+            m
+        } else {
+            let m = Model {
+                label: label.to_string(),
+                path: ResourceReference::from_reference(ResourceReferenceType::Plane),
+                meshes: vec![mesh],
+                materials: vec![material],
+                id: ModelId(hash)
+            };
+            MODEL_CACHE.lock().insert(label, m.clone());
+            m
+        };
+
+
+        Ok(AdoptedEntity::adopt(graphics, model).await)
+    }
+}
diff --git a/dropbear-engine/src/scene.rs b/dropbear-engine/src/scene.rs
index 17bd9fd..8dcf0bc 100644
--- a/dropbear-engine/src/scene.rs
+++ b/dropbear-engine/src/scene.rs
@@ -1,13 +1,17 @@
+// yeah this lint is required to be allowed because winit doesn't use async
+// logically, it wouldn't be possible to deadlock
+#![allow(clippy::await_holding_lock)]
+
 use winit::event_loop::ActiveEventLoop;
 
 use crate::input;
-use std::{cell::RefCell, collections::HashMap, rc::Rc};
+use std::{collections::HashMap, rc::Rc};
+use parking_lot::RwLock;
 
-#[async_trait::async_trait]
 pub trait Scene {
-    async fn load<'a>(&mut self, graphics: &mut crate::graphics::RenderContext<'a>);
-    async fn update<'a>(&mut self, dt: f32, graphics: &mut crate::graphics::RenderContext<'a>);
-    async fn render<'a>(&mut self, graphics: &mut crate::graphics::RenderContext<'a>);
+    fn load(&mut self, graphics: &mut crate::graphics::RenderContext);
+    fn update(&mut self, dt: f32, graphics: &mut crate::graphics::RenderContext);
+    fn render(&mut self, graphics: &mut crate::graphics::RenderContext);
     fn exit(&mut self, event_loop: &ActiveEventLoop);
     /// By far a mess of a trait however it works.
     ///
@@ -33,7 +37,7 @@ impl Default for SceneCommand {
     }
 }
 
-pub type SceneImpl = Rc<RefCell<dyn Scene>>;
+pub type SceneImpl = Rc<RwLock<dyn Scene>>;
 
 #[derive(Clone)]
 pub struct Manager {
@@ -43,6 +47,12 @@ pub struct Manager {
     scene_input_map: HashMap<String, String>,
 }
 
+impl Default for Manager {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl Manager {
     pub fn new() -> Self {
         Self {
@@ -62,7 +72,7 @@ impl Manager {
         }
     }
 
-    pub fn add(&mut self, name: &str, scene: Rc<RefCell<dyn Scene>>) {
+    pub fn add(&mut self, name: &str, scene: SceneImpl) {
         self.scenes.insert(name.to_string(), scene);
     }
 
@@ -71,7 +81,7 @@ impl Manager {
             .insert(scene_name.to_string(), input_name.to_string());
     }
 
-    pub async fn update<'a>(
+    pub fn update<'a>(
         &mut self,
         dt: f32,
         graphics: &mut crate::graphics::RenderContext<'a>,
@@ -79,30 +89,33 @@ impl Manager {
     ) {
         // transition scene
         if let Some(next_scene_name) = self.next_scene.take() {
-            if let Some(current_scene_name) = &self.current_scene {
-                if let Some(scene) = self.scenes.get_mut(current_scene_name) {
-                    scene.borrow_mut().exit(event_loop);
+            if let Some(current_scene_name) = &self.current_scene
+                && let Some(scene) = self.scenes.get_mut(current_scene_name) {
+                { scene.write().exit(event_loop); }
                 }
-            }
             if let Some(scene) = self.scenes.get_mut(&next_scene_name) {
-                scene.borrow_mut().load(graphics).await;
+                { scene.write().load(graphics); }
             }
             self.current_scene = Some(next_scene_name);
         }
 
         // update scene
-        if let Some(scene_name) = &self.current_scene {
-            if let Some(scene) = self.scenes.get_mut(scene_name) {
-                scene.borrow_mut().update(dt, graphics).await;
-                let command = scene.borrow_mut().run_command();
+        if let Some(scene_name) = &self.current_scene
+            && let Some(scene) = self.scenes.get_mut(scene_name) {
+                {
+                    scene.write()
+                        .update(dt, graphics);
+                }
+                let command = scene.write().run_command();
                 match command {
                     SceneCommand::SwitchScene(target) => {
                         if let Some(current) = &self.current_scene {
                             if current == &target {
                                 // reload the scene
                                 if let Some(scene) = self.scenes.get_mut(current) {
-                                    scene.borrow_mut().exit(event_loop);
-                                    scene.borrow_mut().load(graphics).await;
+                                    scene.write().exit(event_loop);
+                                    scene.write().load(graphics);
+
                                     log::debug!("Reloaded scene: {}", current);
                                 }
                             } else {
@@ -120,14 +133,13 @@ impl Manager {
                     SceneCommand::DebugMessage(msg) => log::debug!("{}", msg),
                 }
             }
-        }
     }
 
-    pub async fn render<'a>(&mut self, graphics: &mut crate::graphics::RenderContext<'a>) {
-        if let Some(scene_name) = &self.current_scene {
-            if let Some(scene) = self.scenes.get_mut(scene_name) {
-                scene.borrow_mut().render(graphics).await;
-            }
+    pub fn render<'a>(&mut self, graphics: &mut crate::graphics::RenderContext<'a>) {
+        if let Some(scene_name) = &self.current_scene
+            && let Some(scene) = self.scenes.get_mut(scene_name)
+        {
+            scene.write().render(graphics)
         }
     }
 
@@ -167,7 +179,7 @@ pub fn add_scene_with_input<
 >(
     scene_manager: &mut Manager,
     input_manager: &mut input::Manager,
-    scene: Rc<RefCell<S>>,
+    scene: Rc<RwLock<S>>,
     scene_name: &str,
 ) {
     scene_manager.add(scene_name, scene.clone());
diff --git a/dropbear-engine/src/starter/mod.rs b/dropbear-engine/src/starter/mod.rs
deleted file mode 100644
index 6ec27ef..0000000
--- a/dropbear-engine/src/starter/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-//! Starter objects like planes, players and more
-
-pub mod plane;
diff --git a/dropbear-engine/src/starter/plane.rs b/dropbear-engine/src/starter/plane.rs
deleted file mode 100644
index 823e038..0000000
--- a/dropbear-engine/src/starter/plane.rs
+++ /dev/null
@@ -1,265 +0,0 @@
-use std::hash::{DefaultHasher, Hash, Hasher};
-use crate::entity::AdoptedEntity;
-use crate::graphics::{SharedGraphicsContext, Texture};
-use crate::model::{Material, Mesh, Model, ModelId, ModelVertex, MODEL_CACHE};
-use crate::utils::{ResourceReference, ResourceReferenceType};
-use futures::executor::block_on;
-use image::GenericImageView;
-/// A straight plane (and some components). Thats it.
-///
-/// Inspiration taken from `https://github.com/4tkbytes/RedLight/blob/main/src/RedLight/Entities/Plane.cs`,
-/// my old game engine made in C sharp, where this is the plane "algorithm".
-use std::sync::Arc;
-use wgpu::{AddressMode, util::DeviceExt};
-
-/// Lazily creates a new Plane. This can only be accessed through the Default trait (which you shouldn't use),
-/// or the [`PlaneBuilder::lazy_build()`] (also taken from [`PlaneBuilder::new()`]).
-#[derive(Default)]
-pub struct LazyPlaneBuilder {
-    rgba_data: Vec<u8>,
-    dimensions: (u32, u32),
-    width: f32,
-    height: f32,
-    tiles_x: u32,
-    tiles_z: u32,
-    label: Option<String>,
-}
-
-impl LazyPlaneBuilder {
-    pub fn poke(self, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<AdoptedEntity> {
-        let mut hasher = DefaultHasher::new();
-
-        let mut vertices = Vec::new();
-        let mut indices = Vec::new();
-
-        for z in 0..=1 {
-            for x in 0..=1 {
-                let position = [
-                    (x as f32 - 0.5) * self.width,
-                    0.0,
-                    (z as f32 - 0.5) * self.height,
-                ];
-                let normal = [0.0, 1.0, 0.0];
-                let tex_coords = [
-                    x as f32 * self.tiles_x as f32,
-                    z as f32 * self.tiles_z as f32,
-                ];
-
-                let _ = position.iter().map(|v| (*v as i32).hash(&mut hasher));
-                let _ = normal.iter().map(|v| (*v as i32).hash(&mut hasher));
-                let _ = tex_coords.iter().map(|v| (*v as i32).hash(&mut hasher));
-
-                vertices.push(ModelVertex {
-                    position,
-                    tex_coords,
-                    normal,
-                });
-            }
-        }
-
-        indices.extend_from_slice(&[0, 2, 1, 1, 2, 3]);
-        indices.hash(&mut hasher);
-
-        let vertex_buffer = graphics
-            .device
-            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: Some(&format!("{:?} Vertex Buffer", self.label.as_deref())),
-                contents: bytemuck::cast_slice(&vertices),
-                usage: wgpu::BufferUsages::VERTEX,
-            });
-        let index_buffer = graphics
-            .device
-            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: Some(&format!("{:?} Index Buffer", self.label.as_deref())),
-                contents: bytemuck::cast_slice(&indices),
-                usage: wgpu::BufferUsages::INDEX,
-            });
-
-        let mesh = Mesh {
-            name: "plane".to_string(),
-            vertex_buffer,
-            index_buffer,
-            num_elements: indices.len() as u32,
-            material: 0,
-        };
-
-        let diffuse_texture = Texture::new_with_sampler_with_rgba_buffer(
-            graphics.clone(),
-            &self.rgba_data,
-            self.dimensions,
-            AddressMode::Repeat,
-        );
-        let bind_group = diffuse_texture.bind_group().clone();
-        let material = Material {
-            name: "plane_material".to_string(),
-            diffuse_texture,
-            bind_group,
-        };
-
-        let model = Model {
-            label: self.label.as_deref().unwrap_or("Plane").to_string(),
-            path: ResourceReference::from_reference(ResourceReferenceType::Plane),
-            meshes: vec![mesh],
-            materials: vec![material],
-            id: ModelId(hasher.finish())
-        };
-
-        Ok(block_on(AdoptedEntity::adopt(graphics, model)))
-    }
-}
-
-/// Creates a plane in the form of an AdoptedEntity.
-pub struct PlaneBuilder {
-    width: f32,
-    height: f32,
-    tiles_x: u32,
-    tiles_z: u32,
-}
-
-impl PlaneBuilder {
-    pub fn new() -> Self {
-        Self {
-            width: 10.0,
-            height: 10.0,
-            tiles_x: 0,
-            tiles_z: 0,
-        }
-    }
-
-    pub fn with_size(mut self, width: f32, height: f32) -> Self {
-        self.width = width;
-        self.height = height;
-        self
-    }
-
-    pub fn with_tiles(mut self, tiles_x: u32, tiles_z: u32) -> Self {
-        self.tiles_x = tiles_x;
-        self.tiles_z = tiles_z;
-        self
-    }
-
-    pub async fn lazy_build(
-        mut self,
-        texture_bytes: &[u8],
-        label: Option<&str>,
-    ) -> anyhow::Result<LazyPlaneBuilder> {
-        if self.tiles_x == 0 && self.tiles_z == 0 {
-            self.tiles_x = self.width as u32;
-            self.tiles_z = self.height as u32;
-        }
-
-        let img = image::load_from_memory(texture_bytes)?;
-        let rgba = img.to_rgba8();
-        let dimensions = img.dimensions();
-
-        Ok(LazyPlaneBuilder {
-            rgba_data: rgba.into_raw(),
-            dimensions,
-            width: self.width,
-            height: self.height,
-            tiles_x: self.tiles_x,
-            tiles_z: self.tiles_z,
-            label: label.map(|s| s.to_string()),
-        })
-    }
-
-    pub async fn build(
-        mut self,
-        graphics: Arc<SharedGraphicsContext>,
-        texture_bytes: &[u8],
-        label: Option<&str>,
-    ) -> anyhow::Result<AdoptedEntity> {
-        let label = if let Some(label) = label {label.to_string()} else {format!("{}*{}_tx{}xtz{}_plane", self.width, self.height, self.tiles_x, self.tiles_z)};
-        let mut hasher = DefaultHasher::new();
-        if self.tiles_x == 0 && self.tiles_z == 0 {
-            self.tiles_x = self.width as u32;
-            self.tiles_z = self.height as u32;
-        }
-        let mut vertices = Vec::new();
-        let mut indices = Vec::new();
-
-        for z in 0..=1 {
-            for x in 0..=1 {
-                let position = [
-                    (x as f32 - 0.5) * self.width,
-                    0.0,
-                    (z as f32 - 0.5) * self.height,
-                ];
-                let normal = [0.0, 1.0, 0.0];
-                let tex_coords = [
-                    x as f32 * self.tiles_x as f32,
-                    z as f32 * self.tiles_z as f32,
-                ];
-                let _ = position.iter().map(|v| (*v as i32).hash(&mut hasher));
-                let _ = normal.iter().map(|v| (*v as i32).hash(&mut hasher));
-                let _ = tex_coords.iter().map(|v| (*v as i32).hash(&mut hasher));
-
-                vertices.push(ModelVertex {
-                    position,
-                    tex_coords,
-                    normal,
-                });
-            }
-        }
-
-        indices.extend_from_slice(&[0, 2, 1, 1, 2, 3]);
-        indices.hash(&mut hasher);
-
-        let hash = hasher.finish();
-
-        let model = if let Some(cached_model) = MODEL_CACHE.lock().get(&label.clone()) {
-            log::debug!("Model loaded from cache: {:?}", label.clone());
-            Some(cached_model.clone())
-        } else {None};
-
-        let vertex_buffer = graphics
-            .device
-            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: Some(&format!("{:?} Vertex Buffer", label.clone())),
-                contents: bytemuck::cast_slice(&vertices),
-                usage: wgpu::BufferUsages::VERTEX,
-            });
-        let index_buffer = graphics
-            .device
-            .create_buffer_init(&wgpu::util::BufferInitDescriptor {
-                label: Some(&format!("{:?} Index Buffer", label)),
-                contents: bytemuck::cast_slice(&indices),
-                usage: wgpu::BufferUsages::INDEX,
-            });
-
-        let mesh = Mesh {
-            name: "plane".to_string(),
-            vertex_buffer,
-            index_buffer,
-            num_elements: indices.len() as u32,
-            material: 0,
-        };
-
-        let diffuse_texture =
-            Texture::new_with_sampler(graphics.clone(), texture_bytes, AddressMode::Repeat);
-        let bind_group = diffuse_texture.bind_group().clone();
-        let material = Material {
-            name: "plane_material".to_string(),
-            diffuse_texture,
-            bind_group,
-        };
-
-        let model = if model.is_none() {
-            let m = Model {
-                label: label.to_string(),
-                path: ResourceReference::from_reference(ResourceReferenceType::Plane),
-                meshes: vec![mesh],
-                materials: vec![material],
-                id: ModelId(hash)
-            };
-            MODEL_CACHE.lock().insert(label, m.clone());
-            m
-        } else {
-            // safe to do
-            model.unwrap()
-        };
-
-
-        Ok(AdoptedEntity::adopt(graphics, model).await)
-    }
-}
diff --git a/dropbear-engine/src/utils.rs b/dropbear-engine/src/utils.rs
index 05b44b1..2ce2e24 100644
--- a/dropbear-engine/src/utils.rs
+++ b/dropbear-engine/src/utils.rs
@@ -31,7 +31,7 @@ pub enum ResourceReferenceType {
     /// A simple plane. Some of the types in [`ResourceReferenceType`] can be simple, just as a signal
     /// to load that entity as a plane or another type.
     ///
-    /// In specifics, the plane (as from [`crate::starter::plane::PlaneBuilder`]) is a model that
+    /// In specifics, the plane (as from [`crate::procedural::plane::PlaneBuilder`]) is a model that
     /// has meshes and a textured material, but is created "in house" (during runtime instead of loaded).
     Plane,
 }
@@ -50,12 +50,11 @@ impl Default for ResourceReferenceType {
 ///
 /// The resource reference will be `models/cube.obj`.
 ///
-/// - If ran in the editor, it translates to
-/// `/home/tk/project/resources/models/cube.obj`.
+/// - If ran in the editor, it translates to `/home/tk/project/resources/models/cube.obj`.
 ///
 /// - In the runtime (with redback-runtime), it
-/// translates to `/home/tk/Downloads/Maze/resources/models/cube.obj`
-/// _(assuming the executable is at `/home/tk/Downloads/Maze/maze_runner.exe`)_.
+///   translates to `/home/tk/Downloads/Maze/resources/models/cube.obj`
+///   _(assuming the executable is at `/home/tk/Downloads/Maze/maze_runner.exe`)_.
 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct ResourceReference {
     pub ref_type: ResourceReferenceType,
@@ -104,8 +103,8 @@ impl ResourceReference {
         let components: Vec<_> = path.components().collect();
 
         for (i, component) in components.iter().enumerate() {
-            if let std::path::Component::Normal(name) = component {
-                if *name == "resources" {
+            if let std::path::Component::Normal(name) = component
+                && *name == "resources" {
                     let remaining_components = &components[i + 1..];
                     if remaining_components.is_empty() {
                         anyhow::bail!("Unable to locate any remaining components");
@@ -124,7 +123,6 @@ impl ResourceReference {
                         ref_type: ResourceReferenceType::File(resource_path),
                     });
                 }
-            }
         }
 
         anyhow::bail!("Nothing here")
@@ -184,11 +182,10 @@ impl ResourceReference {
                 anyhow::bail!("Cannot resolve bytes")
             }
             ResourceReferenceType::File(path) => {
-                if let Ok(exe_path) = self.to_executable_path() {
-                    if exe_path.exists() {
+                if let Ok(exe_path) = self.to_executable_path()
+                    && exe_path.exists() {
                         return Ok(exe_path);
                     }
-                }
 
                 Ok(std::env::current_dir()?
                     .join("resources")
diff --git a/dropbear_future-queue/Cargo.toml b/dropbear_future-queue/Cargo.toml
new file mode 100644
index 0000000..8daa5f4
--- /dev/null
+++ b/dropbear_future-queue/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "dropbear_future-queue"
+
+version.workspace = true
+edition.workspace = true
+repository.workspace = true
+license = "MIT"
+readme = "README.md"
+description = "A queue for polling futures in a synchronous context"
+
+[dependencies]
+ahash = "0.8"
+parking_lot.workspace = true
+tokio = { version = "1", features = ["rt", "sync", "time", "rt-multi-thread"] }
+
+[dev-dependencies]
+tokio = { version = "1", features = ["rt", "sync", "time", "rt-multi-thread", "macros"] }
+tokio-test = "0.4"
diff --git a/dropbear_future-queue/README.md b/dropbear_future-queue/README.md
new file mode 100644
index 0000000..fdbc37b
--- /dev/null
+++ b/dropbear_future-queue/README.md
@@ -0,0 +1,31 @@
+# dropbear-futurequeue
+
+A helper queue for polling futures in single threaded systems such as in winit.
+
+## Example
+
+```rust
+// create new queue
+let queue = FutureQueue::new();
+
+// create a new handle to keep for reference
+let handle = queue.push(async move {
+    tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
+    67 + 41
+});
+
+// check initial status
+assert!(matches!(queue.get_status(&handle), Some(FutureStatus::NotPolled)));
+
+// execute the futures
+queue.poll();
+
+// wait for the task to do its job (this can be simulated with an update loop)
+tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
+
+// check the result
+if let Some(result) = queue.exchange_as::<i32>(&handle) {
+    println!("67 + 41 = {}", result);
+    assert_eq!(result, 108);
+}
+```
diff --git a/dropbear_future-queue/src/lib.rs b/dropbear_future-queue/src/lib.rs
new file mode 100644
index 0000000..27bf7b3
--- /dev/null
+++ b/dropbear_future-queue/src/lib.rs
@@ -0,0 +1,417 @@
+//! Enabling multithreading for functions and apps that are purely single threaded.
+//!
+//! This was originally a module in my [dropbear](https://github.com/4tkbytes/dropbear) game engine,
+//! however I thought there were barely any libraries that had future queuing. It takes inspiration
+//! from Unity and how they handle their events.
+//!
+//! # Example
+//! ```rust
+//! use dropbear_future_queue::{FutureQueue, FutureStatus};
+//!
+//! # tokio_test::block_on(async {
+//! // create new queue
+//! let queue = FutureQueue::new();
+//!
+//! // create a new handle to keep for reference
+//! let handle = queue.push(async move {
+//!     tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
+//!     67 + 41
+//! });
+//!
+//! // Check initial status
+//! assert!(matches!(queue.get_status(&handle), Some(FutureStatus::NotPolled)));
+//!
+//! // execute the futures
+//! queue.poll();
+//!
+//! // Wait a bit for completion and check result
+//! tokio::time::sleep(tokio::time::Duration::from_millis(20)).await;
+//!
+//! if let Some(result) = queue.exchange_as::<i32>(&handle) {
+//!     println!("67 + 41 = {}", result);
+//!     assert_eq!(result, 108);
+//! }
+//! # });
+//! ```
+
+use std::any::Any;
+use std::cell::RefCell;
+use std::collections::VecDeque;
+use std::pin::Pin;
+use std::sync::Arc;
+use ahash::{HashMap, HashMapExt};
+use parking_lot::Mutex;
+use tokio::sync::oneshot;
+use std::future::Future;
+use std::rc::Rc;
+
+/// A type used for a future.
+///
+/// It must include a [`Send`] trait to be usable for the [`FutureQueue`]
+pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
+/// A clonable generic result. It can/preferred to be downcasted to your specific type.
+pub type AnyResult = Arc<dyn Any + Send + Sync>;
+/// Internal function: A result receiver
+type ResultReceiver = oneshot::Receiver<AnyResult>;
+/// A type for storing the queue. It uses a [`VecDeque`] to store [`FutureHandle`]'s and [`BoxFuture`]
+pub type FutureStorage = Arc<Mutex<VecDeque<(FutureHandle, BoxFuture<()>)>>>;
+/// A type recommended to be used by [`FutureQueue`] to allow being thrown around in your app
+pub type Throwable<T> = Rc<RefCell<T>>;
+
+/// A status showing the future, used by the [`ResultReceiver`] and [`ResultSender`]
+#[derive(Clone, Debug)]
+pub enum FutureStatus {
+    NotPolled,
+    CurrentlyPolling,
+    Completed,
+}
+
+/// A handle to the future task
+#[derive(Default, Copy, Clone, Eq, Hash, PartialEq, Debug)]
+pub struct FutureHandle {
+    pub id: u64,
+}
+
+/// Internal storage per handle — separate from FutureHandle
+struct HandleEntry {
+    receiver: Option<ResultReceiver>,
+    status: FutureStatus,
+    cached_result: Option<AnyResult>,
+}
+
+/// A queue for polling futures. It is stored in here until [`FutureQueue::poll`] is run.
+pub struct FutureQueue {
+    /// The queue for the futures.
+    queued: FutureStorage,
+    /// A place to store all handle data
+    handle_registry: Arc<Mutex<HashMap<FutureHandle, HandleEntry>>>,
+    /// Next id to be processed
+    next_id: Arc<Mutex<u64>>,
+}
+
+impl FutureQueue {
+    /// Creates a new [`Arc<FutureQueue>`].
+    pub fn new() -> Self {
+        Self {
+            queued: Arc::new(Mutex::new(VecDeque::new())),
+            handle_registry: Arc::new(Mutex::new(HashMap::new())),
+            next_id: Arc::new(Mutex::new(0)),
+        }
+    }
+
+    /// Pushes a future to the FutureQueue. It will sit and wait
+    /// to be processed until [`FutureQueue::poll`] is called.
+    pub fn push<F, T>(&self, future: F) -> FutureHandle
+    where
+        F: Future<Output = T> + Send + 'static,
+        T: Send + Sync + 'static,
+    {
+        let mut next_id = self.next_id.lock();
+        let id = *next_id;
+        *next_id += 1;
+
+        let id = FutureHandle { id };
+
+        let (sender, receiver) = oneshot::channel::<AnyResult>();
+
+        let entry = HandleEntry {
+            receiver: Some(receiver),
+            status: FutureStatus::NotPolled,
+            cached_result: None,
+        };
+
+        self.handle_registry.lock().insert(id, entry);
+
+        let wrapped_future: Pin<Box<dyn Future<Output = ()> + Send>> = Box::pin(async move {
+            log("Starting future execution");
+            let result = future.await;
+            let boxed_result: AnyResult = Arc::new(result);
+            log("Future completed, sending result");
+
+            let _ = sender.send(boxed_result);
+
+            // Don't update status here - let the exchange method handle it
+            log("Result sent via channel");
+        });
+
+        self.queued.lock().push_back((id, wrapped_future));
+
+        id
+    }
+
+    /// Polls all the futures in the future queue and resolves the handles.
+    ///
+    /// This function spawns a new async thread for each item inside the thread and
+    /// sends updates to the Handle's receiver.
+    pub fn poll(&self) {
+        let mut queue = self.queued.lock();
+        log("Locked queue for polling");
+
+        if queue.is_empty() {
+            log("Queue is empty, nothing to poll");
+            return;
+        }
+
+        let mut futures_to_spawn = Vec::new();
+
+        while let Some((id, future)) = queue.pop_front() {
+            log(format!("Processing future with id: {:?}", id));
+
+            {
+                let mut registry = self.handle_registry.lock();
+                if let Some(entry) = registry.get_mut(&id) {
+                    entry.status = FutureStatus::CurrentlyPolling;
+                    log("Updated status to CurrentlyPolling");
+                }
+            }
+
+            futures_to_spawn.push(future);
+        }
+
+        drop(queue);
+
+        for future in futures_to_spawn {
+            log("Spawning future with tokio");
+            tokio::spawn(future);
+        }
+    }
+
+    /// Exchanges the future for the result.
+    ///
+    /// When the handle is not successful, it will return nothing. When the handle is successful,
+    /// it will return the result. The result is cached and can be retrieved multiple times.
+    pub fn exchange(&self, handle: &FutureHandle) -> Option<AnyResult> {
+        let mut registry = self.handle_registry.lock();
+        if let Some(entry) = registry.get_mut(handle) {
+            match &entry.status {
+                FutureStatus::Completed => {
+                    log("FutureStatus::Completed - returning cached result");
+                    entry.cached_result.clone()
+                }
+                _ => {
+                    log("Future not completed yet, checking receiver");
+                    if let Some(receiver) = entry.receiver.as_mut() {
+                        match receiver.try_recv() {
+                            Ok(result) => {
+                                log("Received result from channel");
+                                entry.status = FutureStatus::Completed;
+                                entry.cached_result = Some(result.clone());
+                                entry.receiver = None; // Remove receiver as it's no longer needed
+                                Some(result)
+                            }
+                            Err(oneshot::error::TryRecvError::Empty) => {
+                                log("Channel is empty - future still running");
+                                None
+                            }
+                            Err(oneshot::error::TryRecvError::Closed) => {
+                                log("Channel is closed - future may have panicked");
+                                None
+                            }
+                        }
+                    } else {
+                        log("No receiver available");
+                        None
+                    }
+                }
+            }
+        } else {
+            log("Handle not found in registry");
+            None
+        }
+    }
+
+    /// Exchanges the future for the result, taking ownership and consuming the cached result.
+    ///
+    /// When the handle is not successful, it will return nothing. When the handle is successful,
+    /// it will return the result and remove it from the cache, allowing Arc::try_unwrap to succeed.
+    /// This method can only be called once per completed future.
+    pub fn exchange_owned(&self, handle: &FutureHandle) -> Option<AnyResult> {
+        let mut registry = self.handle_registry.lock();
+        if let Some(entry) = registry.get_mut(handle) {
+            match &entry.status {
+                FutureStatus::Completed => {
+                    log("FutureStatus::Completed - taking ownership of cached result");
+                    entry.cached_result.take()
+                }
+                _ => {
+                    log("Future not completed yet, checking receiver");
+                    if let Some(receiver) = entry.receiver.as_mut() {
+                        match receiver.try_recv() {
+                            Ok(result) => {
+                                log("Received result from channel");
+                                entry.status = FutureStatus::Completed;
+                                entry.receiver = None; // Remove receiver as it's no longer needed
+                                Some(result)
+                            }
+                            Err(oneshot::error::TryRecvError::Empty) => {
+                                log("Channel is empty - future still running");
+                                None
+                            }
+                            Err(oneshot::error::TryRecvError::Closed) => {
+                                log("Channel is closed - future may have panicked");
+                                None
+                            }
+                        }
+                    } else {
+                        log("No receiver available");
+                        None
+                    }
+                }
+            }
+        } else {
+            log("Handle not found in registry");
+            None
+        }
+    }
+
+    /// Exchanges the handle and safely downcasts it into a specific type.
+    pub fn exchange_as<T: Any + Send + Sync + 'static>(&self, handle: &FutureHandle) -> Option<T> {
+        self.exchange(handle)?
+            .downcast::<T>()
+            .ok()
+            .and_then(|arc| Arc::try_unwrap(arc).ok())
+    }
+
+    /// Exchanges the handle taking ownership and safely downcasts it into a specific type.
+    /// This method consumes the cached result, allowing Arc::try_unwrap to succeed.
+    pub fn exchange_owned_as<T: Any + Send + Sync + 'static>(&self, handle: &FutureHandle) -> Option<T> {
+        self.exchange_owned(handle)?
+            .downcast::<T>()
+            .ok()
+            .and_then(|arc| Arc::try_unwrap(arc).ok())
+    }
+
+    /// Get status of a handle
+    pub fn get_status(&self, handle: &FutureHandle) -> Option<FutureStatus> {
+        let registry = self.handle_registry.lock();
+        registry.get(handle).map(|entry| entry.status.clone())
+    }
+
+    /// Cleans up any completed handles and removes them from the registry.
+    ///
+    /// You can do this manually, however this is typically done at the end of the frame.
+    pub fn cleanup(&self) {
+        let mut registry = self.handle_registry.lock();
+        let completed_ids: Vec<FutureHandle> = registry
+            .iter()
+            .filter_map(|(&id, entry)| {
+                matches!(entry.status, FutureStatus::Completed).then_some(id)
+            })
+            .collect();
+
+        for id in completed_ids {
+            registry.remove(&id);
+        }
+    }
+}
+
+
+/// Internal function for logging to a file for tests (when stdout is not available).
+///
+/// Only logs if the [`LOG_TO_FILE`] constant is set to true.
+#[cfg(test)]
+fn log(msg: impl ToString) {
+    use std::io::Write;
+
+    let mut file = std::fs::OpenOptions::new().append(true).create(true).open("test.log").unwrap();
+    file.write_all(format!("{}\n", msg.to_string()).as_bytes()).unwrap();
+}
+
+#[cfg(not(test))]
+fn log(_msg: impl ToString) {
+
+}
+
+impl Default for FutureQueue {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[test]
+fn test_future_queue() {
+    tokio::runtime::Builder::new_multi_thread()
+    .enable_all()
+    .build()
+    .unwrap()
+    .block_on(async {
+        let queue = FutureQueue::new();
+        log("Created new queue");
+
+        let handle = queue.push(async move {
+            log("Inside the pushed future - starting work");
+            tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
+            log("Inside the pushed future - work completed");
+            67 + 41
+        });
+        log("Created new handle");
+
+        queue.poll();
+        log("Initial poll completed");
+
+        let mut attempts = 0;
+        let max_attempts = 100;
+        let start_time = std::time::Instant::now();
+
+        loop {
+            attempts += 1;
+            log(format!("Attempt {}: Checking for result", attempts));
+            log(format!("Time since start: {} ms", start_time.elapsed().as_millis()));
+
+            if let Some(result) = queue.exchange(&handle) {
+                let result = result.downcast::<i32>().unwrap();
+                log(format!("Success! 67 + 41 = {}", result));
+                assert_eq!(*result, 108);
+                break;
+            }
+
+            if attempts >= max_attempts {
+                log("Max attempts reached - test failed");
+                panic!("Future never completed");
+            }
+
+            tokio::time::sleep(tokio::time::Duration::from_millis(1)).await;
+        }
+
+        log("Test completed successfully");
+    });
+}
+
+// #[tokio::test]
+#[test]
+fn test_exchange_owned_as() {
+    tokio::runtime::Builder::new_multi_thread()
+    .enable_all()
+    .build()
+    .unwrap()
+    .block_on(async {
+        let queue = FutureQueue::new();
+
+        let handle = queue.push(async move {
+            tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
+            67 + 41
+        });
+
+        queue.poll();
+
+        let mut attempts = 0;
+        let max_attempts = 100;
+
+        loop {
+            attempts += 1;
+
+            if let Some(result) = queue.exchange_owned_as::<i32>(&handle) {
+                assert_eq!(result, 108);
+                break;
+            }
+
+            if attempts >= max_attempts {
+                panic!("Future never completed");
+            }
+
+            tokio::time::sleep(tokio::time::Duration::from_millis(1)).await;
+        }
+
+        assert!(queue.exchange_owned_as::<i32>(&handle).is_none());
+    });
+}
\ No newline at end of file
diff --git a/eucalyptus-core/Cargo.toml b/eucalyptus-core/Cargo.toml
index 6507faf..9d3b22e 100644
--- a/eucalyptus-core/Cargo.toml
+++ b/eucalyptus-core/Cargo.toml
@@ -23,7 +23,7 @@ parking_lot.workspace = true
 ron.workspace = true
 serde.workspace = true
 winit.workspace = true
-zip.workspace = true
+# zip.workspace = true
 tokio.workspace = true
 boa_engine.workspace = true
 rayon.workspace = true
@@ -31,8 +31,8 @@ rayon.workspace = true
 [features]
 editor = []
 
-[target.'cfg(not(target_os = "android"))'.dependencies]
-rfd.workspace = true
+# [target.'cfg(not(target_os = "android"))'.dependencies]
+# rfd.workspace = true
 
 [build-dependencies]
 anyhow = "1.0"
diff --git a/eucalyptus-core/src/camera.rs b/eucalyptus-core/src/camera.rs
index 585700b..a4eae2d 100644
--- a/eucalyptus-core/src/camera.rs
+++ b/eucalyptus-core/src/camera.rs
@@ -12,6 +12,12 @@ pub struct CameraComponent {
     pub camera_type: CameraType,
 }
 
+impl Default for CameraComponent {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl CameraComponent {
     pub fn new() -> Self {
         Self {
@@ -35,6 +41,7 @@ impl CameraComponent {
 pub struct PlayerCamera;
 
 impl PlayerCamera {
+    #[allow(clippy::new_ret_no_self)]
     pub fn new() -> CameraComponent {
         CameraComponent {
             camera_type: CameraType::Player,
@@ -70,6 +77,7 @@ impl PlayerCamera {
 pub struct DebugCamera;
 
 impl DebugCamera {
+    #[allow(clippy::new_ret_no_self)]
     pub fn new() -> CameraComponent {
         CameraComponent {
             camera_type: CameraType::Debug,
diff --git a/eucalyptus-core/src/lib.rs b/eucalyptus-core/src/lib.rs
index 0235c5e..b60b60a 100644
--- a/eucalyptus-core/src/lib.rs
+++ b/eucalyptus-core/src/lib.rs
@@ -5,3 +5,4 @@ pub mod logging;
 pub mod scripting;
 pub mod states;
 pub mod utils;
+pub mod spawn;
diff --git a/eucalyptus-core/src/scripting.rs b/eucalyptus-core/src/scripting.rs
index b87fade..e56a357 100644
--- a/eucalyptus-core/src/scripting.rs
+++ b/eucalyptus-core/src/scripting.rs
@@ -4,36 +4,28 @@ use boa_engine::property::PropertyKey;
 use boa_engine::{Context, JsString, JsValue, Source};
 use dropbear_engine::entity::{AdoptedEntity, Transform};
 use hecs::{Entity, World};
-use parking_lot::RwLock;
 use std::path::PathBuf;
 use std::str::FromStr;
-use std::sync::Arc;
 use std::{collections::HashMap, fs};
 
-pub const TEMPLATE_SCRIPT: &'static str = include_str!("../../resources/template.ts");
-
-pub enum ScriptAction {
-    AttachScript {
-        script_path: PathBuf,
-        script_name: String,
-    },
-    CreateAndAttachScript {
-        script_path: PathBuf,
-        script_name: String,
-    },
-    RemoveScript,
-    EditScript,
-}
+pub const TEMPLATE_SCRIPT: &str = include_str!("../../resources/template.ts");
 
 #[derive(Clone)]
 pub struct DropbearScriptingAPIContext {
     pub current_entity: Option<Entity>,
-    current_world: Option<Arc<RwLock<World>>>,
+    // fyi: im pretty sure this is safe because I can just null with [`Option::None`]
+    current_world: Option<*const World>,
     pub current_input: Option<InputState>,
     pub persistent_data: HashMap<String, Value>,
     pub frame_data: HashMap<String, Value>,
 }
 
+impl Default for DropbearScriptingAPIContext {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl DropbearScriptingAPIContext {
     pub fn new() -> Self {
         Self {
@@ -45,9 +37,9 @@ impl DropbearScriptingAPIContext {
         }
     }
 
-    pub fn set_context(&mut self, entity: Entity, world: Arc<RwLock<World>>, input: &InputState) {
+    pub fn set_context(&mut self, entity: Entity, world: &mut World, input: &InputState) {
         self.current_entity = Some(entity);
-        self.current_world = Some(world);
+        self.current_world = Some(world as *mut World);
         self.current_input = Some(input.clone());
     }
 
@@ -120,7 +112,7 @@ impl ScriptManager {
         &mut self,
         entity_id: hecs::Entity,
         script_name: &str,
-        world: Arc<RwLock<World>>,
+        world: &mut World,
         input_state: &InputState,
     ) -> anyhow::Result<()> {
         log_once::debug_once!("init_entity_script: {} for {:?}", script_name, entity_id);
@@ -157,7 +149,7 @@ impl ScriptManager {
             }
 
             self.script_context.clear_context();
-            return Ok(());
+            Ok(())
         } else {
             Err(anyhow::anyhow!("Script '{}' not found", script_name))
         }
@@ -167,7 +159,7 @@ impl ScriptManager {
         &mut self,
         entity_id: hecs::Entity,
         script_name: &str,
-        world: Arc<RwLock<World>>,
+        world: &mut World,
         input_state: &InputState,
         dt: f32,
     ) -> anyhow::Result<()> {
@@ -175,7 +167,7 @@ impl ScriptManager {
 
         if let Some(module) = self.compiled_scripts.get(script_name).cloned() {
             self.script_context
-                .set_context(entity_id, world.clone(), input_state);
+                .set_context(entity_id, world, input_state);
 
             let mut context = Context::default();
             self.expose(&mut context);
@@ -300,14 +292,14 @@ pub fn move_script_to_src(script_path: &PathBuf) -> anyhow::Result<PathBuf> {
 }
 
 pub fn convert_entity_to_group(
-    world: Arc<RwLock<World>>,
+    world: &mut World,
     entity_id: hecs::Entity,
 ) -> anyhow::Result<EntityNode> {
-    if let Ok(mut query) = world.read().query_one::<(&AdoptedEntity, &Transform)>(entity_id) {
+    if let Ok(mut query) = world.query_one::<(&AdoptedEntity, &Transform)>(entity_id) {
         if let Some((adopted, _transform)) = query.get() {
             let entity_name = adopted.model.label.clone();
 
-            let script_node = if let Ok(script) = world.read().get::<&ScriptComponent>(entity_id) {
+            let script_node = if let Ok(script) = world.get::<&ScriptComponent>(entity_id) {
                 Some(EntityNode::Script {
                     name: script.name.clone(),
                     path: script.path.clone(),
@@ -339,12 +331,12 @@ pub fn convert_entity_to_group(
 }
 
 pub fn attach_script_to_entity(
-    world: Arc<RwLock<World>>,
+    world: &mut World,
     entity_id: hecs::Entity,
     script_component: ScriptComponent,
 ) -> anyhow::Result<()> {
     {
-        if let Err(e) = world.write().insert_one(entity_id, script_component) {
+        if let Err(e) = world.insert_one(entity_id, script_component) {
             return Err(anyhow::anyhow!("Failed to attach script to entity: {}", e));
         }
     }
@@ -352,3 +344,16 @@ pub fn attach_script_to_entity(
     log::info!("Successfully attached script to entity {:?}", entity_id);
     Ok(())
 }
+
+pub enum ScriptAction {
+    AttachScript {
+        script_path: PathBuf,
+        script_name: String,
+    },
+    CreateAndAttachScript {
+        script_path: PathBuf,
+        script_name: String,
+    },
+    RemoveScript,
+    EditScript,
+}
diff --git a/eucalyptus-core/src/spawn.rs b/eucalyptus-core/src/spawn.rs
new file mode 100644
index 0000000..f1bb1c1
--- /dev/null
+++ b/eucalyptus-core/src/spawn.rs
@@ -0,0 +1,46 @@
+use std::sync::{Arc, LazyLock};
+use parking_lot::Mutex;
+use dropbear_engine::entity::{Transform};
+use dropbear_engine::future::{FutureHandle, FutureQueue};
+use dropbear_engine::graphics::SharedGraphicsContext;
+use dropbear_engine::utils::ResourceReference;
+use crate::states::ModelProperties;
+
+/// All spawns that are waiting to be spawned in.
+pub static PENDING_SPAWNS: LazyLock<Mutex<Vec<PendingSpawn>>> =
+    LazyLock::new(|| Mutex::new(Vec::new()));
+
+/// A spawn that's waiting to be added into the world. 
+#[derive(Clone, Debug)]
+pub struct PendingSpawn {
+    /// A [`ResourceReference`] to the asset
+    pub asset_path: ResourceReference,
+    /// The name/label of the asset
+    pub asset_name: String,
+    /// The [`Transform`] properties (position)
+    pub transform: Transform,
+    /// The properties of a model, as specified in [`ModelProperties`]
+    pub properties: ModelProperties,
+    /// An optional future handle to an object.
+    /// 
+    /// If one is specified, it is assumed that the returned object is an [`AdoptedEntity`](dropbear_engine::entity::AdoptedEntity).
+    /// 
+    /// If one is NOT specified, it will be created based off the information provided. It is **recommended** to set it to [`None`]. 
+    pub handle: Option<FutureHandle>,
+}
+
+/// Extension trait for checking the editor (or anything else) for any spawns
+/// that are waiting to be polled and added
+pub trait PendingSpawnController {
+    /// Checks up on the spawn list and spawns them into the world after it has been
+    /// asynchronously loaded.
+    /// 
+    /// This is expected to be run on the update loop. 
+    fn check_up(&mut self, graphics: Arc<SharedGraphicsContext>, queue: Arc<FutureQueue>) -> anyhow::Result<()>;
+}
+
+/// Helper function to spawn a [`PendingSpawn`]
+pub fn push_pending_spawn(spawn: PendingSpawn) {
+    log::debug!("Pushing spawn");
+    PENDING_SPAWNS.lock().push(spawn);
+}
\ No newline at end of file
diff --git a/eucalyptus-core/src/states.rs b/eucalyptus-core/src/states.rs
index 25fc43a..a5d019d 100644
--- a/eucalyptus-core/src/states.rs
+++ b/eucalyptus-core/src/states.rs
@@ -2,12 +2,12 @@ use crate::camera::DebugCamera;
 use crate::camera::{CameraComponent, CameraFollowTarget, CameraType};
 use crate::utils::PROTO_TEXTURE;
 use chrono::Utc;
-use dropbear_engine::camera::Camera;
+use dropbear_engine::camera::{Camera, CameraBuilder};
 use dropbear_engine::entity::{AdoptedEntity, Transform};
 use dropbear_engine::graphics::SharedGraphicsContext;
 use dropbear_engine::lighting::{Light, LightComponent};
 use dropbear_engine::model::Model;
-use dropbear_engine::starter::plane::PlaneBuilder;
+use dropbear_engine::procedural::plane::PlaneBuilder;
 use dropbear_engine::utils::{ResourceReference, ResourceReferenceType};
 use egui_dock_fork::DockState;
 use glam::DVec3;
@@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize};
 use tokio::sync::mpsc::UnboundedSender;
 use std::collections::HashMap;
 use std::fmt::{Display, Formatter};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::sync::Arc;
 use std::{fmt, fs};
 use rayon::prelude::*;
@@ -52,24 +52,13 @@ pub struct ProjectConfig {
 impl ProjectConfig {
     /// Creates a new instance of the ProjectConfig. This function is typically used when creating
     /// a new project, with it creating new defaults for everything.
-    pub fn new(project_name: String, project_path: &PathBuf) -> Self {
+    pub fn new(project_name: String, project_path: impl AsRef<Path>) -> Self {
         let date_created = format!("{}", Utc::now().format("%Y-%m-%d %H:%M:%S"));
         let date_last_accessed = format!("{}", Utc::now().format("%Y-%m-%d %H:%M:%S"));
-        // #[cfg(not(feature = "editor"))]
-        // {
-        //     let mut result = Self {
-        //         project_name,
-        //         project_path: project_path.to_path_buf(),
-        //         date_created,
-        //         date_last_accessed,
-        //     };
-        //     let _ = result.load_config_to_memory(); // TODO: Deal with later...
-        //     result
-        // }
 
         let mut result = Self {
             project_name,
-            project_path: project_path.to_path_buf(),
+            project_path: project_path.as_ref().to_path_buf(),
             date_created,
             date_last_accessed,
             editor_settings: Default::default(),
@@ -84,15 +73,14 @@ impl ProjectConfig {
     ///
     /// # Parameters
     /// * path - The root **folder** of the project.
-
-    pub fn write_to(&mut self, path: &PathBuf) -> anyhow::Result<()> {
+    pub fn write_to(&mut self, path: impl AsRef<Path>) -> anyhow::Result<()> {
         self.load_config_to_memory()?;
         self.date_last_accessed = format!("{}", Utc::now().format("%Y-%m-%d %H:%M:%S"));
         // self.assets = Assets::walk(path);
         let ron_str = ron::ser::to_string_pretty(&self, PrettyConfig::default())
             .map_err(|e| anyhow::anyhow!("RON serialization error: {}", e))?;
-        let config_path = path.join(format!("{}.eucp", self.project_name.clone().to_lowercase()));
-        self.project_path = path.to_path_buf();
+        let config_path = path.as_ref().join(format!("{}.eucp", self.project_name.clone().to_lowercase()));
+        self.project_path = path.as_ref().to_path_buf();
 
         fs::write(&config_path, ron_str).map_err(|e| anyhow::anyhow!(e.to_string()))?;
         Ok(())
@@ -103,10 +91,10 @@ impl ProjectConfig {
     ///
     /// # Parameters
     /// * path - The root config **file** for the project
-    pub fn read_from(path: &PathBuf) -> anyhow::Result<Self> {
-        let ron_str = fs::read_to_string(path)?;
-        let mut config: ProjectConfig = ron::de::from_str(&ron_str.as_str())?;
-        config.project_path = path.parent().unwrap().to_path_buf();
+    pub fn read_from(path: impl AsRef<Path>) -> anyhow::Result<Self> {
+        let ron_str = fs::read_to_string(path.as_ref())?;
+        let mut config: ProjectConfig = ron::de::from_str(ron_str.as_str())?;
+        config.project_path = path.as_ref().parent().unwrap().to_path_buf();
         log::info!("Loaded project!");
         log::debug!("Loaded config info");
         log::debug!("Updating with new content");
@@ -222,7 +210,7 @@ impl ProjectConfig {
     /// # Parameters
     /// * path - The root folder of the project
     pub fn write_to_all(&mut self) -> anyhow::Result<()> {
-        let path = PathBuf::from(self.project_path.clone());
+        let path = self.project_path.clone();
 
         {
             let resources_config = RESOURCES.read();
@@ -307,15 +295,15 @@ impl ResourceConfig {
 
     /// # Parameters
     /// - path: The root **folder** of the project
-    pub fn write_to(&self, path: &PathBuf) -> anyhow::Result<()> {
-        let resource_dir = path.join("resources");
+    pub fn write_to(&self, path: impl AsRef<Path>) -> anyhow::Result<()> {
+        let resource_dir = path.as_ref().join("resources");
         let updated_config = ResourceConfig {
             path: resource_dir.clone(),
-            nodes: collect_nodes(&resource_dir, path, vec!["thumbnails"].as_slice()),
+            nodes: collect_nodes(&resource_dir, path.as_ref(), vec!["thumbnails"].as_slice()),
         };
         let ron_str = ron::ser::to_string_pretty(&updated_config, PrettyConfig::default())
             .map_err(|e| anyhow::anyhow!("RON serialization error: {}", e))?;
-        let config_path = path.join("resources").join("resources.eucc");
+        let config_path = path.as_ref().join("resources").join("resources.eucc");
         fs::create_dir_all(config_path.parent().unwrap())?;
         fs::write(&config_path, ron_str).map_err(|e| anyhow::anyhow!(e.to_string()))?;
         Ok(())
@@ -334,8 +322,8 @@ impl ResourceConfig {
 
     /// # Parameters
     /// - path: The location to the **resources.eucc** file
-    pub fn read_from(path: &PathBuf) -> anyhow::Result<Self> {
-        let config_path = path.join("resources").join("resources.eucc");
+    pub fn read_from(path: impl AsRef<Path>) -> anyhow::Result<Self> {
+        let config_path = path.as_ref().join("resources").join("resources.eucc");
         let ron_str = fs::read_to_string(&config_path)?;
         let config: ResourceConfig = ron::de::from_str(&ron_str)
             .map_err(|e| anyhow::anyhow!("RON deserialization error: {}", e))?;
@@ -360,16 +348,16 @@ impl SourceConfig {
 
     /// # Parameters
     /// - path: The root **folder** of the project
-    pub fn write_to(&self, path: &PathBuf) -> anyhow::Result<()> {
-        let resource_dir = path.join("src");
+    pub fn write_to(&self, path: impl AsRef<Path>) -> anyhow::Result<()> {
+        let resource_dir = path.as_ref().join("src");
         let updated_config = SourceConfig {
             path: resource_dir.clone(),
-            nodes: collect_nodes(&resource_dir, path, vec!["scripts"].as_slice()),
+            nodes: collect_nodes(&resource_dir, path.as_ref(), vec!["scripts"].as_slice()),
         };
 
         let ron_str = ron::ser::to_string_pretty(&updated_config, PrettyConfig::default())
             .map_err(|e| anyhow::anyhow!("RON serialisation error: {}", e))?;
-        let config_path = path.join("src").join("source.eucc");
+        let config_path = path.as_ref().join("src").join("source.eucc");
         fs::create_dir_all(config_path.parent().unwrap())?;
         fs::write(&config_path, ron_str).map_err(|e| anyhow::anyhow!(e.to_string()))?;
         Ok(())
@@ -377,8 +365,8 @@ impl SourceConfig {
 
     /// # Parameters
     /// - path: The location to the **source.eucc** file
-    pub fn read_from(path: &PathBuf) -> anyhow::Result<Self> {
-        let config_path = path.join("src").join("source.eucc");
+    pub fn read_from(path: impl AsRef<Path>) -> anyhow::Result<Self> {
+        let config_path = path.as_ref().join("src").join("source.eucc");
         let ron_str = fs::read_to_string(&config_path)?;
         let config: SourceConfig = ron::de::from_str(&ron_str)
             .map_err(|e| anyhow::anyhow!("RON deserialization error: {}", e))?;
@@ -386,7 +374,7 @@ impl SourceConfig {
     }
 }
 
-fn collect_nodes(dir: &PathBuf, project_path: &PathBuf, exclude_list: &[&str]) -> Vec<Node> {
+fn collect_nodes(dir: impl AsRef<Path>, project_path: impl AsRef<Path>, exclude_list: &[&str]) -> Vec<Node> {
     let mut nodes = Vec::new();
     if let Ok(entries) = fs::read_dir(dir) {
         for entry in entries.flatten() {
@@ -397,13 +385,13 @@ fn collect_nodes(dir: &PathBuf, project_path: &PathBuf, exclude_list: &[&str]) -
                 .to_string_lossy()
                 .to_string();
 
-            if entry_path.is_dir() && exclude_list.iter().any(|ex| &ex.to_string() == &name) {
+            if entry_path.is_dir() && exclude_list.iter().any(|ex| ex.to_string() == *name) {
                 log::debug!("Skipped past folder {:?}", name);
                 continue;
             }
 
             if entry_path.is_dir() {
-                let folder_nodes = collect_nodes(&entry_path, project_path, exclude_list);
+                let folder_nodes = collect_nodes(&entry_path, project_path.as_ref(), exclude_list);
                 nodes.push(Node::Folder(Folder {
                     name,
                     path: entry_path.clone(),
@@ -426,9 +414,15 @@ fn collect_nodes(dir: &PathBuf, project_path: &PathBuf, exclude_list: &[&str]) -
                     Some(ResourceType::Unknown)
                 };
 
+                // Store relative path from the project root instead of absolute path
+                let relative_path = entry_path
+                    .strip_prefix(project_path.as_ref())
+                    .unwrap_or(&entry_path)
+                    .to_path_buf();
+
                 nodes.push(Node::File(File {
                     name,
-                    path: entry_path.clone(),
+                    path: relative_path,
                     resource_type,
                 }));
             }
@@ -606,16 +600,8 @@ impl CameraConfig {
             far: camera.zfar as f32,
             speed: component.speed as f32,
             sensitivity: component.sensitivity as f32,
-            follow_target_entity_label: if let Some(target) = follow_target {
-                Some(target.follow_target.clone())
-            } else {
-                None
-            },
-            follow_offset: if let Some(target) = follow_target {
-                Some(target.offset.to_array())
-            } else {
-                None
-            },
+            follow_target_entity_label: follow_target.map(|target| target.follow_target.clone()),
+            follow_offset: follow_target.map(|target| target.offset.to_array()),
         }
     }
 }
@@ -683,10 +669,10 @@ pub struct SceneConfig {
 
 impl SceneConfig {
     /// Creates a new instance of the scene config
-    pub fn new(scene_name: String, path: PathBuf) -> Self {
+    pub fn new(scene_name: String, path: impl AsRef<Path>) -> Self {
         Self {
             scene_name,
-            path,
+            path: path.as_ref().to_path_buf(),
             entities: Vec::new(),
             cameras: Vec::new(),
             lights: Vec::new(),
@@ -694,11 +680,11 @@ impl SceneConfig {
     }
 
     /// Write the scene config to a .eucs file
-    pub fn write_to(&self, project_path: &PathBuf) -> anyhow::Result<()> {
+    pub fn write_to(&self, project_path: impl AsRef<Path>) -> anyhow::Result<()> {
         let ron_str = ron::ser::to_string_pretty(&self, PrettyConfig::default())
             .map_err(|e| anyhow::anyhow!("RON serialization error: {}", e))?;
 
-        let scenes_dir = project_path.join("scenes");
+        let scenes_dir = project_path.as_ref().join("scenes");
         fs::create_dir_all(&scenes_dir)?;
 
         let config_path = scenes_dir.join(format!("{}.eucs", self.scene_name));
@@ -707,18 +693,18 @@ impl SceneConfig {
     }
 
     /// Read a scene config from a .eucs file
-    pub fn read_from(scene_path: &PathBuf) -> anyhow::Result<Self> {
-        let ron_str = fs::read_to_string(scene_path)?;
+    pub fn read_from(scene_path: impl AsRef<Path>) -> anyhow::Result<Self> {
+        let ron_str = fs::read_to_string(scene_path.as_ref())?;
         let mut config: SceneConfig = ron::de::from_str(&ron_str)
             .map_err(|e| anyhow::anyhow!("RON deserialization error: {}", e))?;
 
-        config.path = scene_path.clone();
+        config.path = scene_path.as_ref().to_path_buf();
         Ok(config)
     }
 
     pub async fn load_into_world(
         &self,
-        world: Arc<RwLock<hecs::World>>,
+        world: &mut hecs::World,
         graphics: Arc<SharedGraphicsContext>,
         progress_sender: Option<UnboundedSender<WorldLoadingStatus>>
     ) -> anyhow::Result<hecs::Entity> {
@@ -730,9 +716,9 @@ impl SceneConfig {
         log::info!(
             "Loading scene [{}], clearing world with {} entities",
             self.scene_name,
-            world.read().len()
+            world.len()
         );
-        { world.write().clear(); }
+        { world.clear(); }
 
         #[allow(unused_variables)]
         let project_config = if cfg!(feature = "editor") {
@@ -743,7 +729,7 @@ impl SceneConfig {
             PathBuf::new()
         };
 
-        log::info!("World cleared, now has {} entities", world.read().len());
+        log::info!("World cleared, now has {} entities", world.len());
 
         let entity_configs: Vec<(usize, SceneEntity)> = {
             let cloned = self.entities.clone();
@@ -795,9 +781,9 @@ impl SceneConfig {
                             name: script_config.name.clone(),
                             path: script_config.path.clone(),
                         };
-                        { world.write().spawn((adopted, transform, script, entity_config.properties.clone())); }
+                        { world.spawn((adopted, transform, script, entity_config.properties.clone())); }
                     } else {
-                        { world.write().spawn((adopted, transform, entity_config.properties.clone())); }
+                        { world.spawn((adopted, transform, entity_config.properties.clone())); }
                     }
 
                     Ok(())
@@ -821,9 +807,9 @@ impl SceneConfig {
                             name: script_config.name.clone(),
                             path: script_config.path.clone(),
                         };
-                        { world.write().spawn((adopted, transform, script, entity_config.properties.clone())); }
+                        { world.spawn((adopted, transform, script, entity_config.properties.clone())); }
                     } else {
-                        { world.write().spawn((adopted, transform, entity_config.properties.clone())); }
+                        { world.spawn((adopted, transform, entity_config.properties.clone())); }
                     }
 
                     Ok(())
@@ -885,9 +871,9 @@ impl SceneConfig {
                             name: script_config.name.clone(),
                             path: script_config.path.clone(),
                         };
-                        { world.write().spawn((plane, transform, script, entity_config.properties.clone())); }
+                        { world.spawn((plane, transform, script, entity_config.properties.clone())); }
                     } else {
-                        { world.write().spawn((plane, transform, entity_config.properties.clone())); }
+                        { world.spawn((plane, transform, entity_config.properties.clone())); }
                     }
 
                     Ok(())
@@ -911,13 +897,13 @@ impl SceneConfig {
 
             let light = Light::new(
                 graphics.clone(),
-                &light_config.light_component,
-                &light_config.transform,
+                light_config.light_component.clone(),
+                light_config.transform.clone(),
                 Some(&light_config.label),
             )
             .await;
             {
-                world.write().spawn((
+                world.spawn((
                     light_config.light_component.clone(),
                     light_config.transform,
                     light,
@@ -939,15 +925,17 @@ impl SceneConfig {
 
             let camera = Camera::new(
                 graphics.clone(),
-                DVec3::from_array(camera_config.position),
-                DVec3::from_array(camera_config.target),
-                DVec3::from_array(camera_config.up),
-                camera_config.aspect,
-                camera_config.fov as f64,
-                camera_config.near as f64,
-                camera_config.far as f64,
-                camera_config.speed as f64,
-                camera_config.sensitivity as f64,
+                CameraBuilder {
+                    eye: DVec3::from_array(camera_config.position),
+                    target: DVec3::from_array(camera_config.target),
+                    up: DVec3::from_array(camera_config.up),
+                    aspect: camera_config.aspect,
+                    fov_y: camera_config.fov as f64,
+                    znear: camera_config.near as f64,
+                    zfar: camera_config.far as f64,
+                    speed: camera_config.speed as f64,
+                    sensitivity: camera_config.sensitivity as f64,
+                },
                 Some(&camera_config.label),
             );
 
@@ -966,30 +954,37 @@ impl SceneConfig {
                     follow_target: target_label.clone(),
                     offset: DVec3::from_array(*offset),
                 };
-                { world.write().spawn((camera, component, follow_target)); }
+                { world.spawn((camera, component, follow_target)); }
             } else {
-                { world.write().spawn((camera, component)); }
+                { world.spawn((camera, component)); }
             }
         }
 
-        if world.read()
-            .query::<(&LightComponent, &Light)>()
-            .iter()
-            .next()
-            .is_none()
         {
-            log::info!("No lights in scene, spawning default light");
-            if let Some(ref s) = progress_sender {
-                let _ = s.send(WorldLoadingStatus::LoadingLight { index: 0, name: String::from("Default Light"), total: 1 });
+            let mut is_none = false;
+            if world
+                .query::<(&LightComponent, &Light)>()
+                .iter()
+                .next()
+                .is_none()
+            {
+                log::info!("No lights in scene, spawning default light");
+                is_none = true;
             }
-            let comp = LightComponent::directional(glam::DVec3::ONE, 1.0);
-            let trans = Transform {
-                position: glam::DVec3::new(2.0, 4.0, 2.0),
-                ..Default::default()
-            };
-            let light = Light::new(graphics.clone(), &comp, &trans, Some("Default Light")).await;
+            
+            if is_none {
+                if let Some(ref s) = progress_sender {
+                    let _ = s.send(WorldLoadingStatus::LoadingLight { index: 0, name: String::from("Default Light"), total: 1 });
+                }
+                let comp = LightComponent::directional(glam::DVec3::ONE, 1.0);
+                let trans = Transform {
+                    position: glam::DVec3::new(2.0, 4.0, 2.0),
+                    ..Default::default()
+                };
+                let light = Light::new(graphics.clone(), comp.clone(), trans, Some("Default Light")).await;
 
-            world.write().spawn((comp, trans, light, ModelProperties::default()));
+                { world.spawn((comp, trans, light, ModelProperties::default())); }
+            }
         }
 
         log::info!(
@@ -1001,36 +996,40 @@ impl SceneConfig {
         #[cfg(feature = "editor")]
         {
             // Editor mode - look for debug camera, create one if none exists
-            let debug_camera = world.read()
-                .query::<(&Camera, &CameraComponent)>()
-                .iter()
-                .find_map(|(entity, (_, component))| {
-                    if matches!(component.camera_type, CameraType::Debug) {
-                        Some(entity)
-                    } else {
-                        None
-                    }
-                });
+            let debug_camera = {
+                world
+                    .query::<(&Camera, &CameraComponent)>()
+                    .iter()
+                    .find_map(|(entity, (_, component))| {
+                        if matches!(component.camera_type, CameraType::Debug) {
+                            Some(entity)
+                        } else {
+                            None
+                        }
+                    })
+            };
 
-            if let Some(camera_entity) = debug_camera {
-                log::info!("Using existing debug camera for editor");
-                Ok(camera_entity)
-            } else {
-                log::info!("No debug camera found, creating viewport camera for editor");
-                if let Some(ref s) = progress_sender {
-                    let _ = s.send(WorldLoadingStatus::LoadingCamera { index: 0, name: String::from("Viewport Camera"), total: 1 });
+            {
+                if let Some(camera_entity) = debug_camera {
+                    log::info!("Using existing debug camera for editor");
+                    Ok(camera_entity)
+                } else {
+                    log::info!("No debug camera found, creating viewport camera for editor");
+                    if let Some(ref s) = progress_sender {
+                        let _ = s.send(WorldLoadingStatus::LoadingCamera { index: 0, name: String::from("Viewport Camera"), total: 1 });
+                    }
+                    let camera = Camera::predetermined(graphics.clone(), Some("Viewport Camera"));
+                    let component = DebugCamera::new();
+                    let camera_entity = { world.spawn((camera, component)) };
+                    Ok(camera_entity)
                 }
-                let camera = Camera::predetermined(graphics.clone(), Some("Viewport Camera"));
-                let component = DebugCamera::new();
-                let camera_entity = { world.write().spawn((camera, component)) };
-                Ok(camera_entity)
             }
         }
 
         #[cfg(not(feature = "editor"))]
         {
             // Runtime mode - look for player camera, panic if none exists
-            let player_camera = world.read()
+            let player_camera = world
                 .query::<(&Camera, &CameraComponent)>()
                 .iter()
                 .find_map(|(entity, (_, component))| {
diff --git a/eucalyptus-core/src/utils.rs b/eucalyptus-core/src/utils.rs
index 75a76f0..84ed62c 100644
--- a/eucalyptus-core/src/utils.rs
+++ b/eucalyptus-core/src/utils.rs
@@ -1,7 +1,5 @@
-use dropbear_engine::entity::Transform;
-use std::path::PathBuf;
 
-use crate::states::{ModelProperties, Node};
+use crate::states::Node;
 
 pub const PROTO_TEXTURE: &[u8] = include_bytes!("../../resources/proto.png");
 
@@ -39,12 +37,3 @@ pub enum ViewportMode {
     CameraMove,
     Gizmo,
 }
-
-#[derive(Clone, Debug)]
-pub struct PendingSpawn {
-    pub asset_path: PathBuf,
-    pub asset_name: String,
-    pub transform: Transform,
-    pub properties: ModelProperties,
-    pub handle_id: Option<u64>,
-}
diff --git a/eucalyptus-editor/Cargo.toml b/eucalyptus-editor/Cargo.toml
index f70338c..67b75bb 100644
--- a/eucalyptus-editor/Cargo.toml
+++ b/eucalyptus-editor/Cargo.toml
@@ -35,7 +35,6 @@ clap.workspace = true
 walkdir.workspace = true
 zip.workspace = true
 tokio.workspace = true
-async-trait.workspace = true
 reqwest.workspace = true
 flate2.workspace = true
 tar.workspace = true
@@ -52,4 +51,4 @@ editor = ["eucalyptus-core/editor"]
 anyhow = "1.0"
 app_dirs2 = "2.5"
 reqwest = { version = "0.12", features = ["blocking"] }
-zip = "4.3"
\ No newline at end of file
+zip = "4.3"
diff --git a/eucalyptus-editor/src/build/gleam.rs b/eucalyptus-editor/src/build/gleam.rs
index d572eb5..4d29d12 100644
--- a/eucalyptus-editor/src/build/gleam.rs
+++ b/eucalyptus-editor/src/build/gleam.rs
@@ -1,15 +1,15 @@
 use app_dirs2::{AppDataType, app_dir};
 use futures_util::StreamExt;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::process::Command;
 use tokio::fs;
 use tokio::io::AsyncWriteExt;
 use tokio::sync::mpsc::UnboundedSender;
 use crate::APP_INFO;
 
-const GLEAM_VERSION: &'static str = "1.12.0";
-const BUN_VERSION: &'static str = "1.2.22";
-const JAVY_VERSION: &'static str = "6.0.0";
+const GLEAM_VERSION: &str = "1.12.0";
+const BUN_VERSION: &str = "1.2.22";
+const JAVY_VERSION: &str = "6.0.0";
 
 #[derive(Clone)]
 pub enum InstallStatus {
@@ -32,9 +32,9 @@ pub struct GleamScriptCompiler {
 #[allow(dead_code)]
 impl GleamScriptCompiler {
     #[allow(dead_code)]
-    pub fn new(project_location: &PathBuf) -> Self {
+    pub fn new(project_location: impl AsRef<Path>) -> Self {
         GleamScriptCompiler {
-            project_location: project_location.clone(),
+            project_location: project_location.as_ref().to_path_buf(),
         }
     }
 
@@ -183,10 +183,10 @@ impl GleamScriptCompiler {
     }
 
     pub async fn download_gleam(
-        app_dir: &PathBuf,
+        app_dir: impl AsRef<Path>,
         sender: Option<UnboundedSender<InstallStatus>>,
     ) -> anyhow::Result<()> {
-        let gleam_dir = app_dir
+        let gleam_dir = app_dir.as_ref()
             .join("dependencies")
             .join("gleam")
             .join(GLEAM_VERSION);
@@ -195,7 +195,7 @@ impl GleamScriptCompiler {
             log::info!(
                 "Gleam v{} already cached at {}",
                 GLEAM_VERSION,
-                app_dir.display()
+                app_dir.as_ref().display()
             );
             return Ok(());
         }
@@ -210,16 +210,16 @@ impl GleamScriptCompiler {
     }
 
     pub async fn download_bun(
-        app_dir: &PathBuf,
+        app_dir: impl AsRef<Path>,
         sender: Option<UnboundedSender<InstallStatus>>,
     ) -> anyhow::Result<()> {
-        let bun_dir = app_dir.join("dependencies").join("bun").join(BUN_VERSION);
+        let bun_dir = app_dir.as_ref().join("dependencies").join("bun").join(BUN_VERSION);
 
         if bun_dir.exists() {
             log::info!(
                 "Bun v{} already cached at {}",
                 BUN_VERSION,
-                app_dir.display()
+                app_dir.as_ref().display()
             );
             return Ok(());
         }
@@ -234,16 +234,16 @@ impl GleamScriptCompiler {
     }
 
     pub async fn download_javy(
-        app_dir: &PathBuf,
+        app_dir: impl AsRef<Path>,
         sender: Option<UnboundedSender<InstallStatus>>,
     ) -> anyhow::Result<()> {
-        let javy_dir = app_dir.join("dependencies").join("javy").join(JAVY_VERSION);
+        let javy_dir = app_dir.as_ref().join("dependencies").join("javy").join(JAVY_VERSION);
 
         if javy_dir.exists() {
             log::info!(
                 "Javy v{} already cached at {}",
                 JAVY_VERSION,
-                app_dir.display()
+                app_dir.as_ref().display()
             );
             return Ok(());
         }
@@ -259,7 +259,7 @@ impl GleamScriptCompiler {
 
     async fn download_and_extract(
         url: &str,
-        target_dir: &PathBuf,
+        target_dir: impl AsRef<Path>,
         tool_name: &str,
         sender: Option<UnboundedSender<InstallStatus>>,
     ) -> anyhow::Result<()> {
@@ -271,7 +271,7 @@ impl GleamScriptCompiler {
             });
         }
 
-        fs::create_dir_all(target_dir).await?;
+        fs::create_dir_all(target_dir.as_ref()).await?;
 
         if let Some(ref s) = sender {
             let _ = s.send(InstallStatus::InProgress {
@@ -286,7 +286,7 @@ impl GleamScriptCompiler {
         let mut downloaded = 0;
         let mut stream = response.bytes_stream();
 
-        let temp_file = target_dir.join(format!("{}_download", tool_name));
+        let temp_file = target_dir.as_ref().join(format!("{}_download", tool_name));
         let mut file = fs::File::create(&temp_file).await?;
 
         while let Some(item) = stream.next().await {
@@ -336,13 +336,13 @@ impl GleamScriptCompiler {
         Ok(())
     }
 
-    async fn extract_zip(archive: &PathBuf, target_dir: &PathBuf) -> anyhow::Result<()> {
+    async fn extract_zip(archive: impl AsRef<Path>, target_dir: impl AsRef<Path>) -> anyhow::Result<()> {
         let file = std::fs::File::open(archive)?;
         let mut archive = zip::ZipArchive::new(file)?;
 
         for i in 0..archive.len() {
             let mut file = archive.by_index(i)?;
-            let outpath = target_dir.join(file.name());
+            let outpath = target_dir.as_ref().join(file.name());
 
             if file.is_dir() {
                 fs::create_dir_all(&outpath).await?;
@@ -359,22 +359,22 @@ impl GleamScriptCompiler {
         Ok(())
     }
 
-    async fn extract_tar_gz(archive: &PathBuf, target_dir: &PathBuf) -> anyhow::Result<()> {
+    async fn extract_tar_gz(archive: impl AsRef<Path>, target_dir: impl AsRef<Path>) -> anyhow::Result<()> {
         let file = std::fs::File::open(archive)?;
         let tar = flate2::read::GzDecoder::new(file);
         let mut archive = tar::Archive::new(tar);
 
         for entry in archive.entries()? {
             let mut entry = entry?;
-            let path = target_dir.join(entry.path()?);
+            let path = target_dir.as_ref().join(entry.path()?);
             entry.unpack(path)?;
         }
         Ok(())
     }
 
     async fn extract_gz(
-        archive: &PathBuf,
-        target_dir: &PathBuf,
+        archive: impl AsRef<Path>,
+        target_dir: impl AsRef<Path>,
         tool_name: &str,
     ) -> anyhow::Result<()> {
         let file = std::fs::File::open(archive)?;
@@ -388,7 +388,7 @@ impl GleamScriptCompiler {
             tool_name.to_string()
         };
 
-        let output_path = target_dir.join(exe_name);
+        let output_path = target_dir.as_ref().join(exe_name);
         let mut output_file = fs::File::create(&output_path).await?;
         output_file.write_all(&buffer).await?;
 
diff --git a/eucalyptus-editor/src/build/mod.rs b/eucalyptus-editor/src/build/mod.rs
index ff61777..642ead9 100644
--- a/eucalyptus-editor/src/build/mod.rs
+++ b/eucalyptus-editor/src/build/mod.rs
@@ -1,7 +1,7 @@
 pub mod gleam;
 
 use std::{collections::HashMap, fs, path::PathBuf, process::Command};
-
+use std::path::Path;
 use clap::ArgMatches;
 use zip::write::SimpleFileOptions;
 
@@ -62,7 +62,7 @@ pub fn package(project_path: PathBuf, _sub_matches: &ArgMatches) -> anyhow::Resu
 
     println!("Building {} for release", project_name);
     let mut cargo_build = Command::new("cargo")
-        .args(&["build", "--release"])
+        .args(["build", "--release"])
         .current_dir(&runtime_dir)
         .stdout(std::process::Stdio::inherit())
         .stderr(std::process::Stdio::inherit())
@@ -168,16 +168,16 @@ pub fn package(project_path: PathBuf, _sub_matches: &ArgMatches) -> anyhow::Resu
     Ok(())
 }
 
-fn clone_repository(build_dir: &PathBuf) -> anyhow::Result<()> {
+fn clone_repository(build_dir: impl AsRef<Path>) -> anyhow::Result<()> {
     git2::build::RepoBuilder::new().clone(
         "https://github.com/4tkbytes/redback-runtime",
-        &build_dir.join("redback-runtime"),
+        &build_dir.as_ref().join("redback-runtime"),
     )?;
     println!("Repository cloned successfully!");
     Ok(())
 }
 
-fn should_update_repository(repo_dir: &PathBuf) -> anyhow::Result<bool> {
+fn should_update_repository(repo_dir: impl AsRef<Path>) -> anyhow::Result<bool> {
     let repo = match git2::Repository::open(repo_dir) {
         Ok(repo) => repo,
         Err(_) => {
@@ -214,8 +214,8 @@ fn should_update_repository(repo_dir: &PathBuf) -> anyhow::Result<bool> {
     Ok(head != remote_commit)
 }
 
-fn copy_resources_folder(src: &PathBuf, dest: &PathBuf) -> anyhow::Result<()> {
-    std::fs::create_dir_all(dest)?;
+fn copy_resources_folder(src: impl AsRef<Path>, dest: impl AsRef<Path>) -> anyhow::Result<()> {
+    fs::create_dir_all(dest.as_ref())?;
 
     for entry in fs::read_dir(src)? {
         let entry = entry?;
@@ -226,7 +226,7 @@ fn copy_resources_folder(src: &PathBuf, dest: &PathBuf) -> anyhow::Result<()> {
             continue;
         }
 
-        let dest_path = dest.join(&file_name);
+        let dest_path = dest.as_ref().join(&file_name);
 
         if src_path.is_dir() {
             copy_resources_folder(&src_path, &dest_path)?;
@@ -238,7 +238,7 @@ fn copy_resources_folder(src: &PathBuf, dest: &PathBuf) -> anyhow::Result<()> {
     Ok(())
 }
 
-fn copy_system_libraries(output_dir: &PathBuf) -> anyhow::Result<()> {
+fn copy_system_libraries(output_dir: impl AsRef<Path>) -> anyhow::Result<()> {
     #[cfg(target_os = "windows")]
     {
         let dll_paths = vec![
@@ -251,7 +251,7 @@ fn copy_system_libraries(output_dir: &PathBuf) -> anyhow::Result<()> {
         for dll_path in dll_paths {
             if std::path::Path::new(dll_path).exists() {
                 let dll_name = std::path::Path::new(dll_path).file_name().unwrap();
-                let dest = output_dir.join(dll_name);
+                let dest = output_dir.as_ref().join(dll_name);
                 std::fs::copy(dll_path, dest)?;
                 println!("Copied system library: {}", dll_name.to_string_lossy());
                 break;
@@ -261,7 +261,7 @@ fn copy_system_libraries(output_dir: &PathBuf) -> anyhow::Result<()> {
 
     #[cfg(any(target_os = "linux", target_os = "macos"))]
     {
-        let lib_dir = output_dir.join("lib");
+        let lib_dir = output_dir.as_ref().join("lib");
         std::fs::create_dir_all(&lib_dir)?;
 
         let lib_paths = vec![
@@ -287,28 +287,28 @@ fn copy_system_libraries(output_dir: &PathBuf) -> anyhow::Result<()> {
     Ok(())
 }
 
-fn create_zip_package(source_dir: &PathBuf, zip_path: &PathBuf) -> anyhow::Result<()> {
-    let file = fs::File::create(zip_path)?;
+fn create_zip_package(source_dir: impl AsRef<Path>, zip_path: impl AsRef<Path>) -> anyhow::Result<()> {
+    let file = fs::File::create(zip_path.as_ref())?;
     let mut zip = zip::ZipWriter::new(file);
 
-    let walkdir = walkdir::WalkDir::new(source_dir);
+    let walkdir = walkdir::WalkDir::new(source_dir.as_ref());
     for entry in walkdir {
         let entry = entry?;
         let path = entry.path();
 
         if path.is_file() {
-            let relative_path = path.strip_prefix(source_dir)?;
+            let relative_path = path.strip_prefix(source_dir.as_ref())?;
             let name = relative_path.to_string_lossy();
 
             let options: SimpleFileOptions = Default::default();
-            zip.start_file(name, options.into())?;
+            zip.start_file(name, options)?;
             let mut file = std::fs::File::open(path)?;
             std::io::copy(&mut file, &mut zip)?;
         }
     }
 
     zip.finish()?;
-    println!("Created zip package: {}", zip_path.display());
+    println!("Created zip package: {}", zip_path.as_ref().display());
     Ok(())
 }
 
@@ -362,14 +362,13 @@ pub fn build(
         for entry in fs::read_dir(&script_dir)? {
             let entry = entry?;
             let path = entry.path();
-            if let Some(ext) = path.extension() {
-                if ext == "rhai" {
+            if let Some(ext) = path.extension()
+                && ext == "rhai" {
                     let name = path.file_name().unwrap().to_string_lossy().to_string();
                     let contents = fs::read_to_string(&path)?;
                     println!(" > Copied script info from [{}]", name);
                     scripts.insert(name, contents);
                 }
-            }
         }
     }
 
@@ -496,24 +495,21 @@ fn check_assimp_availability() -> bool {
         }
 
         if let Ok(output) = Command::new("pkg-config")
-            .args(&["--exists", "assimp"])
+            .args(["--exists", "assimp"])
             .output()
-        {
-            if output.status.success() {
+            && output.status.success() {
                 return true;
             }
-        }
 
         #[cfg(target_os = "linux")]
         {
-            if let Ok(output) = Command::new("ldconfig").args(&["-p"]).output() {
-                if output.status.success() {
+            if let Ok(output) = Command::new("ldconfig").args(["-p"]).output()
+                && output.status.success() {
                     let output_str = String::from_utf8_lossy(&output.stdout);
                     if output_str.contains("libassimp") {
                         return true;
                     }
                 }
-            }
         }
     }
 
diff --git a/eucalyptus-editor/src/camera.rs b/eucalyptus-editor/src/camera.rs
index f83bebb..164fd80 100644
--- a/eucalyptus-editor/src/camera.rs
+++ b/eucalyptus-editor/src/camera.rs
@@ -27,7 +27,7 @@ impl InspectableComponent for Camera {
 
                         if resp.changed() {
                             if cfg.old_label_entity.is_none() {
-                                cfg.old_label_entity = Some(entity.clone());
+                                cfg.old_label_entity = Some(*entity);
                                 cfg.label_original = Some(self.label.clone());
                             }
                             cfg.label_last_edit = Some(Instant::now());
@@ -77,7 +77,7 @@ impl InspectableComponent for Camera {
 pub enum UndoableCameraAction {
     Speed(Entity, f64),
     Sensitivity(Entity, f64),
-    FOV(Entity, f64),
+    Fov(Entity, f64),
     Type(Entity, CameraType),
 }
 
diff --git a/eucalyptus-editor/src/editor/component.rs b/eucalyptus-editor/src/editor/component.rs
index c439108..bff4cd1 100644
--- a/eucalyptus-editor/src/editor/component.rs
+++ b/eucalyptus-editor/src/editor/component.rs
@@ -53,21 +53,20 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed X transform change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -80,21 +79,20 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed Y transform change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -108,21 +106,20 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed Z transform change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -158,8 +155,8 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
@@ -168,15 +165,14 @@ impl InspectableComponent for Transform {
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed X rotation change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -199,8 +195,8 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
@@ -209,15 +205,14 @@ impl InspectableComponent for Transform {
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed Y rotation change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -240,8 +235,8 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
@@ -250,15 +245,14 @@ impl InspectableComponent for Transform {
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed Z rotation change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -298,8 +292,8 @@ impl InspectableComponent for Transform {
                         );
 
                         if response.drag_started() {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
@@ -313,15 +307,14 @@ impl InspectableComponent for Transform {
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed X scale change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -335,8 +328,8 @@ impl InspectableComponent for Transform {
                         let response = ui.add_enabled(!cfg.scale_locked, y_slider);
 
                         if response.drag_started() && !cfg.scale_locked {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
@@ -345,15 +338,14 @@ impl InspectableComponent for Transform {
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed Y scale change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -367,8 +359,8 @@ impl InspectableComponent for Transform {
                         let response = ui.add_enabled(!cfg.scale_locked, z_slider);
 
                         if response.drag_started() && !cfg.scale_locked {
-                            cfg.transform_old_entity = Some(entity.clone());
-                            cfg.transform_original_transform = Some((*self).clone());
+                            cfg.transform_old_entity = Some(*entity);
+                            cfg.transform_original_transform = Some(*self);
                             cfg.transform_in_progress = true;
                         }
 
@@ -377,15 +369,14 @@ impl InspectableComponent for Transform {
                         }
 
                         if response.drag_stopped() && cfg.transform_in_progress {
-                            if let Some(ent) = cfg.transform_old_entity.take() {
-                                if let Some(orig) = cfg.transform_original_transform.take() {
+                            if let Some(ent) = cfg.transform_old_entity.take()
+                                && let Some(orig) = cfg.transform_original_transform.take() {
                                     UndoableAction::push_to_undo(
                                         undo_stack,
                                         UndoableAction::Transform(ent, orig),
                                     );
                                     log::debug!("Pushed Z scale change to undo stack");
                                 }
-                            }
                             cfg.transform_in_progress = false;
                         }
                     });
@@ -424,8 +415,8 @@ impl InspectableComponent for ScriptComponent {
                 .default_open(true)
                 .show(ui, |ui| {
                     ui.horizontal(|ui| {
-                        if ui.button("Browse").clicked() {
-                            if let Some(script_file) = rfd::FileDialog::new()
+                        if ui.button("Browse").clicked()
+                            && let Some(script_file) = rfd::FileDialog::new()
                                 .add_filter("Typescript", &["ts"])
                                 .pick_file()
                             {
@@ -435,7 +426,7 @@ impl InspectableComponent for ScriptComponent {
                                     .to_string_lossy()
                                     .to_string();
                                 let lib_path = &script_file.clone().parent().unwrap().join("dropbear.ts");
-                                if let Err(_) = std::fs::read(lib_path) {
+                                if std::fs::read(lib_path).is_err() {
                                     log::warn!("dropbear.ts library does not exist in project source directory, copying...");
                                     if let Err(e) = std::fs::write(lib_path, include_str!("../../../resources/dropbear.ts")) {
                                         log::error!("Non-fatal error: Creating library file failed: {}", e);
@@ -448,10 +439,9 @@ impl InspectableComponent for ScriptComponent {
                                     script_name,
                                 });
                             }
-                        }
 
-                        if ui.button("New").clicked() {
-                            if let Some(script_path) = rfd::FileDialog::new()
+                        if ui.button("New").clicked()
+                            && let Some(script_path) = rfd::FileDialog::new()
                                 .add_filter("TypeScript", &["ts"])
                                 .set_file_name(format!("{}_script.ts", label))
                                 .save_file()
@@ -459,7 +449,7 @@ impl InspectableComponent for ScriptComponent {
                                 // check if dropbear module exists
                                 // todo: change this to an %APPDATA% file instead of to memory. 
                                 let lib_path = &script_path.clone().parent().unwrap().join("dropbear.ts");
-                                if let Err(_) = std::fs::read(lib_path) {
+                                if std::fs::read(lib_path).is_err() {
                                     log::warn!("dropbear.ts library does not exist in project source directory, copying...");
                                     if let Err(e) = std::fs::write(lib_path, include_str!("../../../resources/dropbear.ts")) {
                                         log::error!("Non-fatal error: Creating library file failed: {}", e);
@@ -484,7 +474,6 @@ impl InspectableComponent for ScriptComponent {
                                     },
                                 }
                             }
-                        }
                     });
 
                     ui.separator();
@@ -527,7 +516,7 @@ impl InspectableComponent for AdoptedEntity {
 
                 if resp.changed() {
                     if cfg.old_label_entity.is_none() {
-                        cfg.old_label_entity = Some(entity.clone());
+                        cfg.old_label_entity = Some(*entity);
                         cfg.label_original = Some(self.model.label.clone());
                     }
                     cfg.label_last_edit = Some(Instant::now());
@@ -572,7 +561,7 @@ impl InspectableComponent for Light {
 
                 if resp.changed() {
                     if cfg.old_label_entity.is_none() {
-                        cfg.old_label_entity = Some(entity.clone());
+                        cfg.old_label_entity = Some(*entity);
                         cfg.label_original = Some(self.label.clone().to_string());
                     }
                     cfg.label_last_edit = Some(Instant::now());
@@ -658,10 +647,10 @@ impl InspectableComponent for LightComponent {
                 ui.horizontal(|ui| {
                     ComboBox::new("Range", "Range")
                         // .width(ui.available_width())
-                        .selected_text(format!("Range {}", self.attenuation.range.to_string()))
+                        .selected_text(format!("Range {}", self.attenuation.range))
                         .show_ui(ui, |ui| {
                             for (preset, label) in ATTENUATION_PRESETS {
-                                ui.selectable_value(&mut self.attenuation, preset.clone(), *label);
+                                ui.selectable_value(&mut self.attenuation, *preset, *label);
                             }
                         });
                 });
diff --git a/eucalyptus-editor/src/editor/dock.rs b/eucalyptus-editor/src/editor/dock.rs
index 66004d1..6091ff1 100644
--- a/eucalyptus-editor/src/editor/dock.rs
+++ b/eucalyptus-editor/src/editor/dock.rs
@@ -4,7 +4,6 @@ use std::{collections::HashSet, sync::LazyLock};
 
 use crate::APP_INFO;
 use crate::editor::component::InspectableComponent;
-use crate::editor::scene::PENDING_SPAWNS;
 use dropbear_engine::{
     entity::Transform,
     lighting::{Light, LightComponent},
@@ -13,17 +12,18 @@ use egui;
 use egui_dock_fork::TabViewer;
 use egui_extras;
 use eucalyptus_core::states::{Node, RESOURCES, ResourceType};
-use eucalyptus_core::utils::PendingSpawn;
 use log;
 use parking_lot::Mutex;
 use transform_gizmo_egui::{EnumSet, Gizmo, GizmoConfig, GizmoExt, GizmoMode, math::DVec3};
+use dropbear_engine::utils::{ResourceReference, ResourceReferenceType};
+use eucalyptus_core::spawn::{push_pending_spawn, PendingSpawn};
 
 pub struct EditorTabViewer<'a> {
     pub view: egui::TextureId,
     pub nodes: Vec<EntityNode>,
     pub tex_size: Extent3d,
     pub gizmo: &'a mut Gizmo,
-    pub world: Arc<RwLock<World>>,
+    pub world: &'a mut World,
     pub selected_entity: &'a mut Option<hecs::Entity>,
     pub viewport_mode: &'a mut ViewportMode,
     pub undo_stack: &'a mut Vec<UndoableAction>,
@@ -40,25 +40,23 @@ impl<'a> EditorTabViewer<'a> {
         position: DVec3,
         properties: Option<ModelProperties>,
     ) -> anyhow::Result<()> {
-        let mut transform = Transform::default();
-        transform.position = position;
+        let transform = Transform { position, ..Default::default() };
         {
-            let mut pending_spawns = PENDING_SPAWNS.lock();
             if let Some(props) = properties {
-                pending_spawns.push(PendingSpawn {
+                push_pending_spawn(PendingSpawn {
                     asset_path: asset.path.clone(),
                     asset_name: asset.name.clone(),
                     transform,
                     properties: props,
-                    handle_id: None,
+                    handle: None,
                 });
             } else {
-                pending_spawns.push(PendingSpawn {
+                push_pending_spawn(PendingSpawn {
                     asset_path: asset.path.clone(),
                     asset_name: asset.name.clone(),
                     transform,
                     properties: ModelProperties::default(),
-                    handle_id: None,
+                    handle: None,
                 });
             }
             Ok(())
@@ -69,7 +67,7 @@ impl<'a> EditorTabViewer<'a> {
 #[derive(Clone, Debug)]
 pub struct DraggedAsset {
     pub name: String,
-    pub path: PathBuf,
+    pub path: ResourceReference,
 }
 
 pub static TABS_GLOBAL: LazyLock<Mutex<StaticallyKept>> =
@@ -117,15 +115,13 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
         let mut cfg = TABS_GLOBAL.lock();
 
         ui.ctx().input(|i| {
-            if i.pointer.button_pressed(egui::PointerButton::Secondary) {
-                if let Some(pos) = i.pointer.hover_pos() {
-                    if ui.available_rect_before_wrap().contains(pos) {
+            if i.pointer.button_pressed(egui::PointerButton::Secondary)
+                && let Some(pos) = i.pointer.hover_pos()
+                    && ui.available_rect_before_wrap().contains(pos) {
                         cfg.show_context_menu = true;
                         cfg.context_menu_pos = pos;
                         cfg.context_menu_tab = Some(tab.clone());
                     }
-                }
-            }
         });
 
         match tab {
@@ -133,7 +129,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                 log_once::debug_once!("Viewport focused");
                 // ------------------- Template for querying active camera -----------------
                 // if let Some(active_camera) = self.active_camera {
-                //     if let Ok(mut q) = self.world.read().query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(*active_camera) {
+                //     if let Ok(mut q) = self.world.query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(*active_camera) {
                 //         if let Some((camera, component, follow_target)) = q.get() {
 
                 //         } else {
@@ -194,7 +190,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                     let active_cam = self.active_camera.lock();
                     if let Some(active_camera) = *active_cam {
                         {
-                            if let Ok(mut q) = self.world.read().query_one::<(
+                            if let Ok(mut q) = self.world.query_one::<(
                                 &Camera,
                                 &CameraComponent,
                                 Option<&CameraFollowTarget>,
@@ -278,9 +274,8 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                             let mut entity_count = 0;
 
                                             {
-                                                let world_read_guard = self.world.read();
                                                 for (entity_id, (transform, _)) in
-                                                    world_read_guard.query::<(&Transform, &AdoptedEntity)>().iter()
+                                                    self.world.query::<(&Transform, &AdoptedEntity)>().iter()
                                                 {
                                                     entity_count += 1;
                                                     let entity_pos = transform.position;
@@ -317,15 +312,13 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                             if let Some(entity_id) = selected_entity_id {
                                                 *self.selected_entity = Some(entity_id);
                                                 log::debug!("Selected entity: {:?}", entity_id);
+                                            } else if entity_count == 0 {
+                                                log::debug!("No entities in world to select");
                                             } else {
-                                                if entity_count == 0 {
-                                                    log::debug!("No entities in world.read() to select");
-                                                } else {
-                                                    log::debug!(
+                                                log::debug!(
                                                     "No entity hit by ray (checked {} entities)",
                                                     entity_count
                                                 );
-                                                }
                                             }
                                         }
                                     }
@@ -355,8 +348,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                 let active_cam = self.active_camera.lock();
                 if let Some(active_camera) = *active_cam {
                     let camera_data = {
-                        let world = self.world.read();
-                        if let Ok(mut q) = world.query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(active_camera) {
+                        if let Ok(mut q) = self.world.query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(active_camera) {
                             let val = q.get();
                             if let Some(val) = val {
                                 Some(val.0.clone())
@@ -383,13 +375,12 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                         });
                     }
                 }
-                if !matches!(self.viewport_mode, ViewportMode::None) {
-                    if let Some(entity_id) = self.selected_entity {
+                if !matches!(self.viewport_mode, ViewportMode::None)
+                    && let Some(entity_id) = self.selected_entity {
                         {
-                            if let Ok(mut q) = self.world.read()
+                            if let Ok(mut q) = self.world
                                 .query_one::<&mut Transform>(*entity_id)
-                            {
-                                if let Some(transform) = q.get() {
+                                && let Some(transform) = q.get() {
                                     let was_focused = cfg.is_focused;
                                     cfg.is_focused = self.gizmo.is_focused();
 
@@ -406,13 +397,11 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
 
                                     if let Some((_result, new_transforms)) =
                                         self.gizmo.interact(ui, &[gizmo_transform])
-                                    {
-                                        if let Some(new_transform) = new_transforms.first() {
+                                        && let Some(new_transform) = new_transforms.first() {
                                             transform.position = new_transform.translation.into();
                                             transform.rotation = new_transform.rotation.into();
                                             transform.scale = new_transform.scale.into();
                                         }
-                                    }
 
                                     if was_focused && !cfg.is_focused {
                                         let transform_changed = cfg.old_pos.position != transform.position
@@ -421,27 +410,25 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
 
                                         if transform_changed {
                                             UndoableAction::push_to_undo(
-                                                &mut self.undo_stack,
+                                                self.undo_stack,
                                                 UndoableAction::Transform(
-                                                    entity_id.clone(),
-                                                    cfg.old_pos.clone(),
+                                                    *entity_id,
+                                                    cfg.old_pos,
                                                 ),
                                             );
                                             log::debug!("Pushed transform action to stack");
                                         }
                                     }
                                 }
-                            }
                         }
                     }
-                }
             }
             EditorTab::ModelEntityList => {
                 ui.label("Model/Entity List");
                 show_entity_tree(
                     ui,
                     &mut self.nodes,
-                    &mut self.selected_entity,
+                    self.selected_entity,
                     "Model Entity Asset List",
                 );
             }
@@ -520,7 +507,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                             ResourceType::Texture => assets.push((
                                                 format!(
                                                     "file://{}",
-                                                    file.path.to_string_lossy().to_string()
+                                                    file.path.to_string_lossy()
                                                 ),
                                                 file.name.clone(),
                                                 file.path.clone(),
@@ -621,13 +608,13 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                             let is_hovered = card_response.hovered() || image_response.hovered() || state.dragged;
                                             let is_d_clicked = card_response.double_clicked() || image_response.double_clicked();
 
-                                            if is_d_clicked {
-                                                if matches!(asset_type, ResourceType::Model) {
+                                            if is_d_clicked
+                                                && matches!(asset_type, ResourceType::Model) {
                                                     let mut spawn_position = DVec3::default();
                                                     {
                                                         let active_cam = self.active_camera.lock();
                                                         if let Some(active_camera) = *active_cam {
-                                                            if let Ok(mut q) = self.world.read().query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(active_camera) {
+                                                            if let Ok(mut q) = self.world.query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(active_camera) {
                                                                 if let Some((camera, _, _)) = q.get() {
                                                                     spawn_position = camera.eye;
                                                                 } else {
@@ -643,7 +630,23 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
 
                                                     let asset = DraggedAsset {
                                                         name: asset_name.clone(),
-                                                        path: asset_path.clone(),
+                                                        path: if asset_path.starts_with("resources/") {
+                                                            // Path is already relative from project root, extract the part after "resources/"
+                                                            ResourceReference {
+                                                                ref_type: ResourceReferenceType::File(
+                                                                    asset_path.strip_prefix("resources/")
+                                                                        .unwrap_or(&asset_path)
+                                                                        .to_string_lossy()
+                                                                        .to_string()
+                                                                ),
+                                                            }
+                                                        } else {
+                                                            // Fallback to the original method for absolute paths
+                                                            ResourceReference::from_path(asset_path.clone()).unwrap_or_else(|_e| { 
+                                                                log::warn!("Unable to create ResourceReference from path: {:?}", asset_path);
+                                                                Default::default() 
+                                                            })
+                                                        },
                                                         // asset_type: asset_type.clone(),
                                                     };
 
@@ -666,7 +669,6 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                                         }
                                                     }
                                                 }
-                                            }
 
                                             if is_hovered || state.dragged {
                                                 ui.painter().rect_filled(
@@ -698,10 +700,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
             EditorTab::ResourceInspector => {
                 if let Some(entity) = self.selected_entity {
                     {
-                        let world = self.world.read();
-                        // Note: Use self.world.read() and query_one instead of self.world.write() and query_one_mut as
-                        // that causes a deadlock
-                            if let Ok(mut q) = world.query_one::<(
+                            if let Ok(mut q) = self.world.query_one::<(
                                 &mut AdoptedEntity,
                                 Option<&mut Transform>,
                                 Option<&ModelProperties>,
@@ -786,28 +785,26 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                         );
                                     }
 
-                                    if let Some(t) = cfg.label_last_edit {
-                                        if t.elapsed() >= Duration::from_millis(500) {
-                                            if let Some(ent) = cfg.old_label_entity.take() {
-                                                if let Some(orig) = cfg.label_original.take() {
+                                    if let Some(t) = cfg.label_last_edit
+                                        && t.elapsed() >= Duration::from_millis(500) {
+                                            if let Some(ent) = cfg.old_label_entity.take()
+                                                && let Some(orig) = cfg.label_original.take() {
                                                     UndoableAction::push_to_undo(
-                                                        &mut self.undo_stack,
+                                                        self.undo_stack,
                                                         UndoableAction::Label(ent, orig, EntityType::Entity),
                                                     );
                                                     log::debug!(
                                             "Pushed label change to undo stack after 500ms debounce period"
                                         );
                                                 }
-                                            }
                                             cfg.label_last_edit = None;
                                         }
-                                    }
                                 }
                             } else {
                                 log_once::debug_once!("Unable to query entity inside resource inspector");
                             }
 
-                            if let Ok(mut q) = world
+                            if let Ok(mut q) = self.world
                                 .query_one::<(&mut Light, &mut Transform, &mut LightComponent)>(*entity)
                             {
                                 if let Some((light, transform, props)) = q.get() {
@@ -835,35 +832,32 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                         self.signal,
                                         &mut light.label,
                                     );
-                                    if let Some(t) = cfg.label_last_edit {
-                                        if t.elapsed() >= Duration::from_millis(500) {
-                                            if let Some(ent) = cfg.old_label_entity.take() {
-                                                if let Some(orig) = cfg.label_original.take() {
+                                    if let Some(t) = cfg.label_last_edit
+                                        && t.elapsed() >= Duration::from_millis(500) {
+                                            if let Some(ent) = cfg.old_label_entity.take()
+                                                && let Some(orig) = cfg.label_original.take() {
                                                     UndoableAction::push_to_undo(
-                                                        &mut self.undo_stack,
+                                                        self.undo_stack,
                                                         UndoableAction::Label(ent, orig, EntityType::Light),
                                                     );
                                                     log::debug!(
                                             "Pushed label change to undo stack after 500ms debounce period"
                                         );
                                                 }
-                                            }
                                             cfg.label_last_edit = None;
                                         }
-                                    }
                                 }
                             } else {
                                 log_once::debug_once!("Unable to query light inside resource inspector");
                             }
 
                             if let Ok(mut q) =
-                                world.query_one::<(
+                                self.world.query_one::<(
                                     &mut Camera,
                                     &mut CameraComponent,
                                     Option<&mut CameraFollowTarget>,
                                 )>(*entity)
-                            {
-                                if let Some((camera, camera_component, follow_target)) = q.get() {
+                                && let Some((camera, camera_component, follow_target)) = q.get() {
                                     camera.inspect(
                                         entity,
                                         &mut cfg,
@@ -895,18 +889,16 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                     ui.label("Camera Controls:");
                                     let mut active_camera = self.active_camera.lock();
                                     if ui.button("Set as Active Camera").clicked() {
-                                        *active_camera = Some(*entity).into();
+                                        *active_camera = Some(*entity);
                                         log::info!("Set camera '{}' as active", camera.label);
                                     }
 
-                                    if matches!(self.editor_mode, EditorState::Editing) {
-                                        if ui.button("Switch to This Camera").clicked() {
-                                            *active_camera = Some(*entity).into();
+                                    if matches!(self.editor_mode, EditorState::Editing)
+                                        && ui.button("Switch to This Camera").clicked() {
+                                            *active_camera = Some(*entity);
                                             log::info!("Switched to camera '{}'", camera.label);
                                         }
-                                    }
                                 }
-                            }
                     }
                 } else {
                     ui.label("No entity selected, therefore no info to provide. Go on, what are you waiting for? Click an entity!");
@@ -966,8 +958,8 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                 })
             });
 
-            if let Some(action) = menu_action {
-                if Some(tab.clone()) == cfg.context_menu_tab {
+            if let Some(action) = menu_action
+                && Some(tab.clone()) == cfg.context_menu_tab {
                     match action {
                         EditorTabMenuAction::ImportResource => {
                             log::debug!("Import Resource clicked");
@@ -1020,26 +1012,22 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                             log::debug!("Add Component clicked");
                             if let Some(entity) = self.selected_entity {
                                 {
-                                    if let Ok(mut q) = self.world.read()
+                                    if let Ok(mut q) = self.world
                                         .query_one::<&AdoptedEntity>(*entity)
-                                    {
-                                        if let Some(..) = q.get() {
+                                        && q.get().is_some() {
                                             log::debug!("Queried selected entity, it is an entity");
                                             *self.signal =
                                                 Signal::AddComponent(*entity, EntityType::Entity);
                                         }
-                                    }
                                 }
 
                                 {
-                                    if let Ok(mut q) = self.world.read()
+                                    if let Ok(mut q) = self.world
                                         .query_one::<&Light>(*entity)
-                                    {
-                                        if let Some(..) = q.get() {
+                                        && q.get().is_some() {
                                             log::debug!("Queried selected entity, it is a light");
                                             *self.signal = Signal::AddComponent(*entity, EntityType::Light);
                                         }
-                                    }
                                 }
                             } else {
                                 warn!(
@@ -1060,7 +1048,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                         EditorTabMenuAction::RemoveComponent => {
                             log::debug!("Remove Component clicked");
                             if let Some(entity) = self.selected_entity {
-                                if let Ok(mut q) = self.world.write()
+                                if let Ok(mut q) = self.world
                                     .query_one::<&ScriptComponent>(*entity)
                                 {
                                     if let Some(script) = q.get() {
@@ -1069,7 +1057,7 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                                         );
                                         *self.signal = Signal::RemoveComponent(
                                             *entity,
-                                            ComponentType::Script(script.clone()),
+                                            Box::new(ComponentType::Script(script.clone())),
                                         );
                                     }
                                 } else {
@@ -1089,23 +1077,17 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                         }
                     }
                 }
-            }
 
-            if let Some(rect) = popup_rect {
-                if cfg.show_context_menu && Some(tab.clone()) == cfg.context_menu_tab {
-                    if ui
+            if let Some(rect) = popup_rect
+                && cfg.show_context_menu && Some(tab.clone()) == cfg.context_menu_tab
+                    && ui
                         .ctx()
                         .input(|i| i.pointer.button_clicked(egui::PointerButton::Primary))
-                    {
-                        if let Some(pos) = ui.ctx().input(|i| i.pointer.interact_pos()) {
-                            if !rect.contains(pos) {
+                        && let Some(pos) = ui.ctx().input(|i| i.pointer.interact_pos())
+                            && !rect.contains(pos) {
                                 cfg.show_context_menu = false;
                                 cfg.context_menu_tab = None;
                             }
-                        }
-                    }
-                }
-            }
         }
     }
 }
@@ -1128,7 +1110,7 @@ pub(crate) fn import_object() -> anyhow::Result<()> {
                     // copy over to models folder
                     {
                         let project = PROJECT.read();
-                        let models_dir = PathBuf::from(project.project_path.clone())
+                        let models_dir = project.project_path.clone()
                             .join("resources")
                             .join("models");
                         if !models_dir.exists() {
@@ -1146,7 +1128,7 @@ pub(crate) fn import_object() -> anyhow::Result<()> {
                     // copy over to textures folder
                     {
                         let project = PROJECT.read();
-                        let textures_dir = PathBuf::from(project.project_path.clone())
+                        let textures_dir = project.project_path.clone()
                             .join("resources")
                             .join("textures");
                         if !textures_dir.exists() {
@@ -1165,7 +1147,7 @@ pub(crate) fn import_object() -> anyhow::Result<()> {
                     let project = PROJECT.read();
                     // everything else copies over to resources root dir
                     let resources_dir =
-                        PathBuf::from(project.project_path.clone()).join("resources");
+                        project.project_path.clone().join("resources");
                     if !resources_dir.exists() {
                         std::fs::create_dir_all(&resources_dir)?;
                     }
@@ -1180,7 +1162,7 @@ pub(crate) fn import_object() -> anyhow::Result<()> {
         proj.write_to_all()?;
         Ok(())
     } else {
-        return Err(anyhow::anyhow!("File dialogue returned None"));
+        Err(anyhow::anyhow!("File dialogue returned None"))
     }
 }
 
diff --git a/eucalyptus-editor/src/editor/input.rs b/eucalyptus-editor/src/editor/input.rs
index 4b0653e..a6ecf25 100644
--- a/eucalyptus-editor/src/editor/input.rs
+++ b/eucalyptus-editor/src/editor/input.rs
@@ -69,7 +69,7 @@ impl Keyboard for Editor {
             }
             KeyCode::Delete => {
                 if !is_playing {
-                    if let Some(_) = &self.selected_entity {
+                    if self.selected_entity.is_some() {
                         self.signal = Signal::Delete;
                     } else {
                         warn!("Failed to delete: No entity selected");
@@ -80,7 +80,7 @@ impl Keyboard for Editor {
             }
             KeyCode::Escape => {
                 if is_double_press {
-                    if let Some(_) = &self.selected_entity {
+                    if self.selected_entity.is_some() {
                         self.selected_entity = None;
                         log::debug!("Deselected entity");
                     }
@@ -114,8 +114,7 @@ impl Keyboard for Editor {
             KeyCode::KeyC => {
                 if ctrl_pressed && !is_playing {
                     if let Some(entity) = &self.selected_entity {
-                        let world = self.world.read();
-                        let query = world
+                        let query = self.world
                             .query_one::<(&AdoptedEntity, &Transform, &ModelProperties)>(*entity);
                         if let Ok(mut q) = query {
                             if let Some((e, t, props)) = q.get() {
@@ -218,11 +217,10 @@ impl Keyboard for Editor {
                 }
             }
             KeyCode::KeyP => {
-                if !is_playing {
-                    if ctrl_pressed {
+                if !is_playing
+                    && ctrl_pressed {
                         self.signal = Signal::Play
                     }
-                }
             }
             _ => {
                 self.input_state.pressed_keys.insert(key);
@@ -247,18 +245,15 @@ impl Mouse for Editor {
                 let dx = position.x - last_pos.0;
                 let dy = position.y - last_pos.1;
 
-                if let Some(active_camera) = *self.active_camera.lock() {
-                    if let Ok(mut q) = self.world.read().query_one::<(
+                if let Some(active_camera) = *self.active_camera.lock()
+                    && let Ok(mut q) = self.world.query_one::<(
                         &mut Camera,
                         &CameraComponent,
                         Option<&CameraFollowTarget>,
                     )>(active_camera)
-                    {
-                        if let Some((camera, _, _)) = q.get() {
+                        && let Some((camera, _, _)) = q.get() {
                             camera.track_mouse_delta(dx, dy);
                         }
-                    }
-                }
             }
             self.input_state.last_mouse_pos = Some((position.x, position.y));
         }
@@ -309,10 +304,8 @@ impl Mouse for Editor {
     }
 
     fn mouse_down(&mut self, button: MouseButton) {
-        match button {
-            _ => {
-                self.input_state.mouse_button.insert(button);
-            }
+        {
+            self.input_state.mouse_button.insert(button);
         }
     }
 
diff --git a/eucalyptus-editor/src/editor/mod.rs b/eucalyptus-editor/src/editor/mod.rs
index abe7b63..814fb2e 100644
--- a/eucalyptus-editor/src/editor/mod.rs
+++ b/eucalyptus-editor/src/editor/mod.rs
@@ -33,22 +33,23 @@ use eucalyptus_core::states::{
     CameraConfig, EditorTab, EntityNode, LightConfig, ModelProperties, PROJECT, SCENES,
     SceneEntity, ScriptComponent,
 };
-use eucalyptus_core::utils::ViewportMode;
+use eucalyptus_core::utils::{ViewportMode};
 use eucalyptus_core::{fatal, info, states, success, warn};
 use hecs::World;
-use log;
-use parking_lot::{Mutex, RwLock};
+use parking_lot::Mutex;
 use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
+use tokio::sync::oneshot;
 use transform_gizmo_egui::{EnumSet, Gizmo, GizmoMode};
 use wgpu::{Color, Extent3d, RenderPipeline};
 use winit::{keyboard::KeyCode, window::Window};
+use dropbear_engine::future::FutureHandle;
 use dropbear_engine::graphics::{RenderContext, Shader};
 use dropbear_engine::model::{ModelId};
 
 pub struct Editor {
     scene_command: SceneCommand,
-    world: Arc<RwLock<World>>,
-    dock_state: Arc<Mutex<DockState<EditorTab>>>,
+    pub world: World,
+    dock_state: DockState<EditorTab>,
     texture_id: Option<egui::TextureId>,
     size: Extent3d,
     render_pipeline: Option<RenderPipeline>,
@@ -63,25 +64,25 @@ pub struct Editor {
 
     show_new_project: bool,
     project_name: String,
-    project_path: Arc<Mutex<Option<PathBuf>>>,
+    pub(crate) project_path: Arc<Mutex<Option<PathBuf>>>,
     pending_scene_switch: bool,
 
     gizmo: Gizmo,
-    selected_entity: Option<hecs::Entity>,
+    pub(crate) selected_entity: Option<hecs::Entity>,
     viewport_mode: ViewportMode,
 
-    signal: Signal,
-    undo_stack: Vec<UndoableAction>,
+    pub(crate) signal: Signal,
+    pub(crate) undo_stack: Vec<UndoableAction>,
     // todo: add redo (later)
     // redo_stack: Vec<UndoableAction>,
-    editor_state: EditorState,
+    pub(crate) editor_state: EditorState,
     gizmo_mode: EnumSet<GizmoMode>,
 
-    script_manager: ScriptManager,
+    pub(crate) script_manager: ScriptManager,
     play_mode_backup: Option<PlayModeBackup>,
 
     /// State of the input
-    input_state: InputState,
+    pub(crate) input_state: InputState,
 
     // channels
     /// A channel for installing dependencies.
@@ -95,6 +96,11 @@ pub struct Editor {
     /// Used to fetch the current status of the loading, so it can be used for different
     /// egui loading windows or splash screens and such.
     current_state: WorldLoadingStatus,
+
+    // handles for futures
+    world_load_handle: Option<FutureHandle>,
+    pub(crate) alt_pending_spawn_queue: Vec<FutureHandle>,
+    world_receiver: Option<oneshot::Receiver<hecs::World>>,
 }
 
 impl Editor {
@@ -109,7 +115,7 @@ impl Editor {
             surface.split_left(NodeIndex::root(), 0.20, vec![EditorTab::ResourceInspector]);
         let [_old, _] = surface.split_below(right, 0.5, vec![EditorTab::AssetViewer]);
 
-        // this shit doesnt work :(
+        // this shit doesn't work :(
         // nvm it works
         std::thread::spawn(move || {
             loop {
@@ -135,7 +141,7 @@ impl Editor {
 
         Self {
             scene_command: SceneCommand::None,
-            dock_state: Arc::new(Mutex::new(dock_state)),
+            dock_state,
             texture_id: None,
             size: Extent3d::default(),
             render_pipeline: None,
@@ -143,7 +149,7 @@ impl Editor {
             is_viewport_focused: false,
             // is_cursor_locked: false,
             window: None,
-            world: Arc::new(RwLock::new(World::new())),
+            world: World::new(),
             show_new_project: false,
             project_name: String::new(),
             project_path: Arc::new(Mutex::new(None)),
@@ -165,6 +171,9 @@ impl Editor {
             progress_tx: None,
             is_world_loaded: IsWorldLoadedYet::new(),
             current_state: WorldLoadingStatus::Idle,
+            world_load_handle: None,
+            alt_pending_spawn_queue: vec![],
+            world_receiver: None,
         }
     }
 
@@ -200,7 +209,7 @@ impl Editor {
         scene.cameras.clear();
 
         for (id, (adopted, transform, properties, script)) in self
-            .world.read()
+            .world
             .query::<(
                 &AdoptedEntity,
                 Option<&Transform>,
@@ -209,7 +218,7 @@ impl Editor {
             )>()
             .iter()
         {
-            let transform = transform.unwrap_or(&Transform::default()).clone();
+            let transform = *transform.unwrap_or(&Transform::default());
 
             let scene_entity = SceneEntity {
                 model_path: adopted.model.path.clone(),
@@ -225,7 +234,7 @@ impl Editor {
         }
 
         for (id, (light_component, transform, light)) in self
-            .world.read()
+            .world
             .query::<(
                 &dropbear_engine::lighting::LightComponent,
                 &Transform,
@@ -246,7 +255,7 @@ impl Editor {
         }
 
         for (_id, (camera, component, follow_target)) in self
-            .world.read()
+            .world
             .query::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>()
             .iter()
         {
@@ -269,8 +278,8 @@ impl Editor {
 
         {
             let mut config = PROJECT.write();
-            let dock_state = self.dock_state.lock();
-            config.dock_layout = Some(dock_state.clone());
+            let dock_state = self.dock_state.clone();
+            config.dock_layout = Some(dock_state);
         }
 
         {
@@ -361,7 +370,8 @@ impl Editor {
         // &mut self,
         graphics: Arc<SharedGraphicsContext>,
         sender: Option<UnboundedSender<WorldLoadingStatus>>,
-        world: Arc<RwLock<World>>,
+        world: &mut World,
+        world_sender: Option<oneshot::Sender<hecs::World>>,
         active_camera: Arc<Mutex<Option<hecs::Entity>>>,
         project_path: Arc<Mutex<Option<PathBuf>>>,
         dock_state: Arc<Mutex<DockState<EditorTab>>>,
@@ -389,7 +399,7 @@ impl Editor {
                     .load_into_world(world, graphics, sender.clone())
                     .await?;
                 let mut a_c = active_camera.lock();
-                *a_c = Some(cam).into();
+                *a_c = Some(cam);
 
                 log::info!(
                     "Successfully loaded scene with {} entities and {} camera configs",
@@ -397,21 +407,23 @@ impl Editor {
                     first_scene.cameras.len(),
                 );
             } else {
-                let existing_debug_camera = world.read()
-                    .query::<(&Camera, &CameraComponent)>()
-                    .iter()
-                    .find_map(|(entity, (_, component))| {
-                        if matches!(component.camera_type, CameraType::Debug) {
-                            Some(entity)
-                        } else {
-                            None
-                        }
-                    });
+                let existing_debug_camera = {
+                    world
+                        .query::<(&Camera, &CameraComponent)>()
+                        .iter()
+                        .find_map(|(entity, (_, component))| {
+                            if matches!(component.camera_type, CameraType::Debug) {
+                                Some(entity)
+                            } else {
+                                None
+                            }
+                        })
+                };
 
                 if let Some(camera_entity) = existing_debug_camera {
                     log::info!("Using existing debug camera");
                     let mut a_c = active_camera.lock();
-                    *a_c = Some(camera_entity).into();
+                    *a_c = Some(camera_entity);
                 } else {
                     log::info!("No scenes found, creating default debug camera");
 
@@ -419,10 +431,10 @@ impl Editor {
                     let component = DebugCamera::new();
 
                     {
-                        let e = world.write()
+                        let e = world
                             .spawn((debug_camera, component));
                         let mut a_c = active_camera.lock();
-                        *a_c = Some(e).into();
+                        *a_c = Some(e);
                     }
                 }
             }
@@ -431,10 +443,15 @@ impl Editor {
         if let Some(ref s) = sender.clone() {
             let _ = s.send(WorldLoadingStatus::Completed);
         }
+
+        if let Some(ws) = world_sender {
+            let _ = ws.send(std::mem::take(world));
+        }
+
         Ok(())
     }
 
-    pub async fn show_ui(&mut self, ctx: &Context) {
+    pub fn show_ui(&mut self, ctx: &Context) {
         egui::TopBottomPanel::top("menu_bar").show(ctx, |ui| {
             egui::MenuBar::new().ui(ui, |ui| {
                 ui.menu_button("File", |ui| {
@@ -459,10 +476,8 @@ impl Editor {
                         if ui.button("Stop").clicked() {
                             self.signal = Signal::StopPlaying;
                         }
-                    } else {
-                        if ui.button("Play").clicked() {
-                            self.signal = Signal::Play;
-                        }
+                    } else if ui.button("Play").clicked() {
+                        self.signal = Signal::Play;
                     }
                     ui.menu_button("Export", |ui| {
                         // todo: create a window for better build menu
@@ -496,8 +511,7 @@ impl Editor {
                 ui.menu_button("Edit", |ui| {
                     if ui.button("Copy").clicked() {
                         if let Some(entity) = &self.selected_entity {
-                            let world = self.world.read();
-                            let query = world.query_one::<(&AdoptedEntity, &Transform, &ModelProperties)>(*entity);
+                            let query = self.world.query_one::<(&AdoptedEntity, &Transform, &ModelProperties)>(*entity);
                             if let Ok(mut q) = query {
                                 if let Some((e, t, props)) = q.get() {
                                     let s_entity = states::SceneEntity {
@@ -541,20 +555,19 @@ impl Editor {
                 });
 
                 ui.menu_button("Window", |ui_window| {
-                    let mut dock_state = self.dock_state.lock();
                     if ui_window.button("Open Asset Viewer").clicked() {
-                        dock_state.push_to_focused_leaf(EditorTab::AssetViewer);
+                        self.dock_state.push_to_focused_leaf(EditorTab::AssetViewer);
                     }
                     if ui_window.button("Open Resource Inspector").clicked() {
-                        dock_state
+                        self.dock_state
                             .push_to_focused_leaf(EditorTab::ResourceInspector);
                     }
                     if ui_window.button("Open Entity List").clicked() {
-                        dock_state
+                        self.dock_state
                             .push_to_focused_leaf(EditorTab::ModelEntityList);
                     }
                     if ui_window.button("Open Viewport").clicked() {
-                        dock_state.push_to_focused_leaf(EditorTab::Viewport);
+                        self.dock_state.push_to_focused_leaf(EditorTab::Viewport);
                     }
                 });
                 {
@@ -566,19 +579,18 @@ impl Editor {
             });
         });
 
-        egui::CentralPanel::default().show(&ctx, |ui| {
-            let mut dock_state = self.dock_state.lock();
-            
-            DockArea::new(&mut dock_state)
+        egui::CentralPanel::default().show(ctx, |ui| {
+
+            DockArea::new(&mut self.dock_state)
                 .style(Style::from_egui(ui.style().as_ref()))
                 .show_inside(
                     ui,
                     &mut EditorTabViewer {
                         view: self.texture_id.unwrap(),
-                        nodes: EntityNode::from_world(&self.world.clone().read()),
+                        nodes: EntityNode::from_world(&self.world),
                         gizmo: &mut self.gizmo,
                         tex_size: self.size,
-                        world: self.world.clone(),
+                        world: &mut self.world,
                         selected_entity: &mut self.selected_entity,
                         viewport_mode: &mut self.viewport_mode,
                         undo_stack: &mut self.undo_stack,
@@ -614,31 +626,31 @@ impl Editor {
             for (entity_id, original_transform, original_properties, original_script) in
                 &backup.entities
             {
-                if let Ok(mut transform) = self.world.read().get::<&mut Transform>(*entity_id) {
+                if let Ok(mut transform) = self.world.get::<&mut Transform>(*entity_id) {
                     *transform = *original_transform;
                 }
 
-                if let Ok(mut properties) = self.world.read().get::<&mut ModelProperties>(*entity_id) {
+                if let Ok(mut properties) = self.world.get::<&mut ModelProperties>(*entity_id) {
                     *properties = original_properties.clone();
                 }
 
-                let has_script = self.world.read().get::<&ScriptComponent>(*entity_id).is_ok();
+                let has_script = self.world.get::<&ScriptComponent>(*entity_id).is_ok();
                 match (has_script, original_script) {
                     (true, Some(original)) => {
-                        if let Ok(mut script) = self.world.read().get::<&mut ScriptComponent>(*entity_id)
+                        if let Ok(mut script) = self.world.get::<&mut ScriptComponent>(*entity_id)
                         {
                             *script = original.clone();
                         }
                     }
                     (true, None) => {
                         {
-                            let _ = self.world.write()
+                            let _ = self.world
                                 .remove_one::<ScriptComponent>(*entity_id);
                         }
                     }
                     (false, Some(original)) => {
                         {
-                            let _ = self.world.write()
+                            let _ = self.world
                                 .insert_one(*entity_id, original.clone());
                         }
                     }
@@ -650,32 +662,32 @@ impl Editor {
             for (entity_id, original_camera, original_component, original_follow_target) in
                 &backup.camera_data
             {
-                if let Ok(mut camera) = self.world.read().get::<&mut Camera>(*entity_id) {
+                if let Ok(mut camera) = self.world.get::<&mut Camera>(*entity_id) {
                     *camera = original_camera.clone();
                 }
 
-                if let Ok(mut component) = self.world.read().get::<&mut CameraComponent>(*entity_id) {
+                if let Ok(mut component) = self.world.get::<&mut CameraComponent>(*entity_id) {
                     *component = original_component.clone();
                 }
 
-                let has_follow_target = self.world.read().get::<&CameraFollowTarget>(*entity_id).is_ok();
+                let has_follow_target = self.world.get::<&CameraFollowTarget>(*entity_id).is_ok();
                 match (has_follow_target, original_follow_target) {
                     (true, Some(original)) => {
                         if let Ok(mut follow_target) =
-                            self.world.read().get::<&mut CameraFollowTarget>(*entity_id)
+                            self.world.get::<&mut CameraFollowTarget>(*entity_id)
                         {
                             *follow_target = original.clone();
                         }
                     }
                     (true, None) => {
                         {
-                            let _ = self.world.write()
+                            let _ = self.world
                                 .remove_one::<CameraFollowTarget>(*entity_id);
                         }
                     }
                     (false, Some(original)) => {
                         {
-                            let _ = self.world.write()
+                            let _ = self.world
                                 .insert_one(*entity_id, original.clone());
                         }
                     }
@@ -698,22 +710,22 @@ impl Editor {
         let mut entities = Vec::new();
 
         for (entity_id, (_, transform, properties)) in self
-            .world.read()
+            .world
             .query::<(&AdoptedEntity, &Transform, &ModelProperties)>()
             .iter()
         {
             let script = self
-                .world.read()
+                .world
                 .query_one::<&ScriptComponent>(entity_id)
                 .ok()
-                .and_then(|mut s| s.get().map(|script| script.clone()));
+                .and_then(|mut s| s.get().cloned());
             entities.push((entity_id, *transform, properties.clone(), script));
         }
 
         let mut camera_data = Vec::new();
 
         for (entity_id, (camera, component, follow_target)) in self
-            .world.read()
+            .world
             .query::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>()
             .iter()
         {
@@ -740,7 +752,7 @@ impl Editor {
 
     pub fn switch_to_debug_camera(&mut self) {
         let debug_camera = self
-            .world.read()
+            .world
             .query::<(&Camera, &CameraComponent)>()
             .iter()
             .find_map(|(e, (_cam, comp))| {
@@ -762,7 +774,7 @@ impl Editor {
 
     pub fn switch_to_player_camera(&mut self) {
         let player_camera = self
-            .world.read()
+            .world
             .query::<(&Camera, &CameraComponent)>()
             .iter()
             .find_map(|(e, (_cam, comp))| {
@@ -784,16 +796,13 @@ impl Editor {
 
     pub fn is_using_debug_camera(&self) -> bool {
         let active_camera = self.active_camera.lock();
-        if let Some(active_camera_entity) = *active_camera {
-            if let Ok(mut query) = self
-                .world.read()
+        if let Some(active_camera_entity) = *active_camera
+            && let Ok(mut query) = self
+                .world
                 .query_one::<&CameraComponent>(active_camera_entity)
-            {
-                if let Some(component) = query.get() {
+                && let Some(component) = query.get() {
                     return matches!(component.camera_type, CameraType::Debug);
                 }
-            }
-        }
         false
     }
 
@@ -811,7 +820,7 @@ impl Editor {
 
         if let Some(active_camera) = *self.active_camera.lock() {
             if let Ok(mut q) = self
-                .world.read()
+                .world
                 .query_one::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>(
                     active_camera,
                 )
@@ -859,7 +868,7 @@ pub static LOGGED: LazyLock<Mutex<HashSet<String>>> = LazyLock::new(|| Mutex::ne
 
 fn show_entity_tree(
     ui: &mut egui::Ui,
-    nodes: &mut Vec<EntityNode>,
+    nodes: &mut [EntityNode],
     selected: &mut Option<hecs::Entity>,
     id_source: &str,
 ) {
@@ -881,7 +890,7 @@ fn show_entity_tree(
                     handle.ui(ui, |ui| {
                         ui.label("📜");
                     });
-                    ui.label(format!("{name}"));
+                    ui.label(name.to_string());
                 });
             }
             EntityNode::Group {
@@ -896,7 +905,7 @@ fn show_entity_tree(
                             .show(ui, |ui| {
                                 show_entity_tree(ui, children, selected, name);
                             });
-                        *collapsed = !header.body_returned.is_some();
+                        *collapsed = header.body_returned.is_none();
                     });
                 });
             }
@@ -949,12 +958,13 @@ fn show_entity_tree(
 pub enum UndoableAction {
     /// A change in transform. The entity + the old transform. Undoing will revert the transform
     Transform(hecs::Entity, Transform),
+    #[allow(dead_code)] // don't know why its considered dead code, todo: check the cause
     /// A spawn of the entity. Undoing will delete the entity
     Spawn(hecs::Entity),
     /// A change of label of the entity. Undoing will revert its label
     Label(hecs::Entity, String, EntityType),
     /// Removing a component. Undoing will add back the component.
-    RemoveComponent(hecs::Entity, ComponentType),
+    RemoveComponent(hecs::Entity, Box<ComponentType>),
     #[allow(dead_code)]
     CameraAction(UndoableCameraAction),
 }
@@ -973,11 +983,11 @@ impl UndoableAction {
         // log::debug!("Undo Stack contents: {:#?}", undo_stack);
     }
 
-    pub fn undo(&self, world: Arc<RwLock<World>>) -> anyhow::Result<()> {
+    pub fn undo(&self, world: &mut World) -> anyhow::Result<()> {
         match self {
             UndoableAction::Transform(entity, transform) => {
                 {
-                    if let Ok(mut q) = world.write().query_one::<&mut Transform>(*entity) {
+                    if let Ok(mut q) = world.query_one::<&mut Transform>(*entity) {
                         if let Some(e_t) = q.get() {
                             *e_t = *transform;
                             log::debug!("Reverted transform");
@@ -991,19 +1001,17 @@ impl UndoableAction {
                 }
             }
             UndoableAction::Spawn(entity) => {
-                {
-                    if world.write().despawn(*entity).is_ok() {
-                        log::debug!("Undid spawn by despawning entity {:?}", entity);
-                        Ok(())
-                    } else {
-                        Err(anyhow::anyhow!("Failed to despawn entity {:?}", entity))
-                    }
+                if world.despawn(*entity).is_ok() {
+                    log::debug!("Undid spawn by despawning entity {:?}", entity);
+                    Ok(())
+                } else {
+                    Err(anyhow::anyhow!("Failed to despawn entity {:?}", entity))
                 }
             }
             UndoableAction::Label(entity, original_label, entity_type) => match entity_type {
                 EntityType::Entity => {
                     {
-                        if let Ok(mut q) = world.write().query_one::<&mut AdoptedEntity>(*entity) {
+                        if let Ok(mut q) = world.query_one::<&mut AdoptedEntity>(*entity) {
                             if let Some(adopted) = q.get() {
                                 Arc::make_mut(&mut adopted.model).label = original_label.clone();
                                 log::debug!(
@@ -1026,7 +1034,7 @@ impl UndoableAction {
                 }
                 EntityType::Light => {
                     {
-                        if let Ok(mut q) = world.write().query_one::<&mut Light>(*entity) {
+                        if let Ok(mut q) = world.query_one::<&mut Light>(*entity) {
                             if let Some(adopted) = q.get() {
                                 adopted.label = original_label.clone();
                                 log::debug!(
@@ -1049,7 +1057,7 @@ impl UndoableAction {
                 }
                 EntityType::Camera => {
                     {
-                        if let Ok(mut q) = world.write().query_one::<&mut Camera>(*entity) {
+                        if let Ok(mut q) = world.query_one::<&mut Camera>(*entity) {
                             if let Some(adopted) = q.get() {
                                 adopted.label = original_label.clone();
                                 log::debug!(
@@ -1072,18 +1080,18 @@ impl UndoableAction {
                 }
             },
             UndoableAction::RemoveComponent(entity, c_type) => {
-                match c_type {
+                match &**c_type {
                     ComponentType::Script(component) => {
-                        { world.write().insert_one(*entity, component.clone())?; }
+                        world.insert_one(*entity, component.clone())?;
                     }
                     ComponentType::Camera(camera, component, follow) => {
                         if let Some(f) = follow {
                             {
-                                world.write()
+                                world
                                     .insert(*entity, (camera.clone(), component.clone(), f.clone()))?;
                             }
                         } else {
-                            { world.write().insert(*entity, (camera.clone(), component.clone()))?; }
+                            world.insert(*entity, (camera.clone(), component.clone()))?;
                         }
                     }
                 }
@@ -1094,49 +1102,41 @@ impl UndoableAction {
                     UndoableCameraAction::Speed(entity, speed) => {
                         {
                             if let Ok(mut q) =
-                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
-                            {
-                                if let Some((cam, comp)) = q.get() {
+                                world.query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
+                                && let Some((cam, comp)) = q.get() {
                                     comp.speed = *speed;
                                     comp.update(cam);
                                 }
-                            }
                         }
                     }
                     UndoableCameraAction::Sensitivity(entity, sensitivity) => {
                         {
                             if let Ok(mut q) =
-                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
-                            {
-                                if let Some((cam, comp)) = q.get() {
+                                world.query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
+                                && let Some((cam, comp)) = q.get() {
                                     comp.sensitivity = *sensitivity;
                                     comp.update(cam);
                                 }
-                            }
                         }
                     }
-                    UndoableCameraAction::FOV(entity, fov) => {
+                    UndoableCameraAction::Fov(entity, fov) => {
                         {
                             if let Ok(mut q) =
-                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
-                            {
-                                if let Some((cam, comp)) = q.get() {
+                                world.query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
+                                && let Some((cam, comp)) = q.get() {
                                     comp.fov_y = *fov;
                                     comp.update(cam);
                                 }
-                            }
                         }
                     }
                     UndoableCameraAction::Type(entity, camera_type) => {
                         {
                             if let Ok(mut q) =
-                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
-                            {
-                                if let Some((cam, comp)) = q.get() {
+                                world.query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
+                                && let Some((cam, comp)) = q.get() {
                                     comp.camera_type = *camera_type;
                                     comp.update(cam);
                                 }
-                            }
                         }
                     }
                 };
@@ -1159,7 +1159,7 @@ pub enum Signal {
     Play,
     StopPlaying,
     AddComponent(hecs::Entity, EntityType),
-    RemoveComponent(hecs::Entity, ComponentType),
+    RemoveComponent(hecs::Entity, Box<ComponentType>),
     CreateEntity,
     LogEntities,
     Spawn(PendingSpawn2),
@@ -1170,7 +1170,7 @@ pub enum Signal {
 // todo: deal with the Camera and create an implementation
 pub enum ComponentType {
     Script(ScriptComponent),
-    Camera(Camera, CameraComponent, Option<CameraFollowTarget>),
+    Camera(Box<Camera>, CameraComponent, Option<CameraFollowTarget>),
 }
 
 #[derive(Clone)]
@@ -1195,10 +1195,10 @@ pub enum EditorState {
 }
 
 pub enum PendingSpawn2 {
-    CreateLight,
-    CreatePlane,
-    CreateCube,
-    CreateCamera,
+    Light,
+    Plane,
+    Cube,
+    Camera,
 }
 
 
@@ -1224,6 +1224,9 @@ impl IsWorldLoadedYet {
         self.project_loaded && self.scene_loaded
     }
 
+    // I don't know whether this should be kept or removed, but 
+    // im adding dead code just in case. 
+    #[allow(dead_code)]
     pub fn is_project_ready(&self) -> bool {
         self.project_loaded
     }
diff --git a/eucalyptus-editor/src/editor/scene.rs b/eucalyptus-editor/src/editor/scene.rs
index 7660bb0..3d04a2b 100644
--- a/eucalyptus-editor/src/editor/scene.rs
+++ b/eucalyptus-editor/src/editor/scene.rs
@@ -1,19 +1,16 @@
 
 use super::*;
 use dropbear_engine::graphics::{InstanceRaw, RenderContext};
-use dropbear_engine::model::{Model, MODEL_CACHE};
-use dropbear_engine::starter::plane::PlaneBuilder;
+use dropbear_engine::model::MODEL_CACHE;
 use dropbear_engine::{
     entity::{AdoptedEntity, Transform},
     lighting::{Light, LightComponent},
     model::{DrawLight, DrawModel},
     scene::{Scene, SceneCommand},
 };
-use egui::{Align2, Image};
 use eucalyptus_core::camera::PlayerCamera;
-use eucalyptus_core::states::{Value, WorldLoadingStatus};
-use eucalyptus_core::utils::{PROTO_TEXTURE, PendingSpawn};
-use eucalyptus_core::{logging, scripting, success_without_console, warn_without_console};
+use eucalyptus_core::states::{WorldLoadingStatus};
+use eucalyptus_core::{logging};
 use hecs::Entity;
 use log;
 use parking_lot::Mutex;
@@ -21,44 +18,45 @@ use tokio::sync::mpsc::unbounded_channel;
 use wgpu::Color;
 use wgpu::util::DeviceExt;
 use winit::{event_loop::ActiveEventLoop, keyboard::KeyCode};
-use std::sync::LazyLock;
+use crate::signal::SignalController;
+use crate::spawn::PendingSpawnController;
 
-pub static PENDING_SPAWNS: LazyLock<Mutex<Vec<PendingSpawn>>> =
-    LazyLock::new(|| Mutex::new(Vec::new()));
-
-#[async_trait::async_trait]
 impl Scene for Editor {
-    async fn load<'a>(&mut self, graphics: &mut RenderContext<'a>) {
+    fn load(&mut self, graphics: &mut RenderContext) {
         let (tx, rx) = unbounded_channel::<WorldLoadingStatus>();
+        let (tx2, rx2) = oneshot::channel::<World>();
         self.progress_tx = Some(rx);
+        self.world_receiver = Some(rx2);
 
         let graphics_shared = graphics.shared.clone();
-        let world_clone = self.world.clone();
         let active_camera_clone = self.active_camera.clone();
         let project_path_clone = self.project_path.clone();
-        let dock_state_clone = self.dock_state.clone();
+        let dock_state_clone = Arc::new(Mutex::new(self.dock_state.clone()));
 
-        tokio::task::spawn_blocking(move || {
-            tokio::runtime::Handle::current().block_on(async {
-                {
-                    if let Err(e) = Self::load_project_config(graphics_shared, Some(tx), world_clone, active_camera_clone, project_path_clone, dock_state_clone).await {
-                        log::error!("Failed to load project config: {}", e);
-                    }
-                }
-            })
+        let handle = graphics.shared.future_queue.push(async move {
+            let mut temp_world = World::new();
+            if let Err(e) = Self::load_project_config(graphics_shared, Some(tx), &mut temp_world, Some(tx2), active_camera_clone, project_path_clone, dock_state_clone).await {
+                log::error!("Failed to load project config: {}", e);
+            }
         });
 
+        self.world_load_handle = Some(handle);
+
         self.window = Some(graphics.shared.window.clone());
         self.is_world_loaded.mark_scene_loaded();
     }
 
-    async fn update<'a>(&mut self, dt: f32, graphics: &mut RenderContext<'a>) {
-        if !self.is_world_loaded.is_project_ready() {
-            log_once::debug_once!("Project is not loaded yet");
+    fn update(&mut self, dt: f32, graphics: &mut RenderContext) {
+        if let Some(mut receiver) = self.world_receiver.take() {
             self.show_project_loading_window(&graphics.shared.get_egui_context());
-            return;
-        } else {
-            log_once::debug_once!("Project has loaded successfully");
+            if let Ok(loaded_world) = receiver.try_recv() {
+                self.world = loaded_world;
+                self.is_world_loaded.mark_project_loaded();
+                log::info!("World received");
+            } else {
+                self.world_receiver = Some(receiver);
+                return;
+            }
         }
 
         if !self.is_world_loaded.is_fully_loaded() {
@@ -74,53 +72,19 @@ impl Scene for Editor {
             return;
         }
 
-        if let Some((_, tab)) = self.dock_state.lock().find_active_focused() {
+        match self.check_up(graphics.shared.clone(), graphics.shared.future_queue.clone()) {
+            Ok(_) => {}
+            Err(e) => {
+                fatal!("{}", e);
+            }
+        }
+
+        if let Some((_, tab)) = self.dock_state.find_active_focused() {
             self.is_viewport_focused = matches!(tab, EditorTab::Viewport);
         } else {
             self.is_viewport_focused = false;
         }
 
-        let spawns_to_process = {
-            let mut pending_spawns = PENDING_SPAWNS.lock();
-            std::mem::take(&mut *pending_spawns)
-        };
-
-        for spawn in spawns_to_process {
-            match AdoptedEntity::new(
-                graphics.shared.clone(),
-                &spawn.asset_path,
-                Some(&spawn.asset_name),
-            )
-            .await
-            {
-                Ok(adopted) => {
-                    let entity_id = {
-                        self.world.write().spawn((
-                            adopted,
-                            spawn.transform,
-                            spawn.properties,
-                        ))
-                    };
-
-                    self.selected_entity = Some(entity_id);
-
-                    UndoableAction::push_to_undo(
-                        &mut self.undo_stack,
-                        UndoableAction::Spawn(entity_id),
-                    );
-
-                    log::info!(
-                        "Successfully spawned {} with ID {:?}",
-                        spawn.asset_name,
-                        entity_id
-                    );
-                }
-                Err(e) => {
-                    log::error!("Failed to spawn {}: {}", spawn.asset_name, e);
-                }
-            }
-        }
-
         if matches!(self.editor_state, EditorState::Playing) {
             if self.input_state.pressed_keys.contains(&KeyCode::Escape) {
                 self.signal = Signal::StopPlaying;
@@ -128,7 +92,7 @@ impl Scene for Editor {
 
             let mut script_entities = Vec::new();
             {
-                for (entity_id, script) in self.world.read()
+                for (entity_id, script) in self.world
                     .query::<&mut ScriptComponent>()
                     .iter()
                 {
@@ -156,7 +120,7 @@ impl Scene for Editor {
                 if let Err(e) = self.script_manager.update_entity_script(
                     entity_id,
                     &script_name,
-                    self.world.clone(),
+                    &mut self.world,
                     &self.input_state,
                     dt,
                 ) {
@@ -193,11 +157,9 @@ impl Scene for Editor {
 
             let active_cam = self.active_camera.lock();
             if let Some(active_camera) = *active_cam {
-                let world = self.world.read();
-                if let Ok(mut query) = world
+                if let Ok(mut query) = self.world
                     .query_one::<(&mut Camera, &CameraComponent)>(active_camera)
-                {
-                    if let Some((camera, component)) = query.get() {
+                    && let Some((camera, component)) = query.get() {
                         match component.camera_type {
                             CameraType::Debug => {
                                 DebugCamera::handle_keyboard_input(camera, &movement_keys);
@@ -225,947 +187,14 @@ impl Scene for Editor {
                             }
                         }
                     }
-                }
             }
 
         }
 
-        match &self.signal {
-            Signal::Paste(scene_entity) => match &scene_entity.model_path.ref_type {
-                dropbear_engine::utils::ResourceReferenceType::None => {
-                    warn!("Resource has a reference type of None");
-                    self.signal = Signal::None;
-                }
-                dropbear_engine::utils::ResourceReferenceType::File(reference) => {
-                    let cloned = {
-                        let project_path = self.project_path.lock();
-                        project_path.clone()
-                    };
-                    if let Some(proj_root) = cloned {
-                        match &scene_entity
-                            .model_path
-                            .to_project_path(proj_root)
-                        {
-                            Some(v) => {
-                                let entity = {
-                                    AdoptedEntity::new(
-                                        graphics.shared.clone(),
-                                        v,
-                                        Some(&scene_entity.label),
-                                    ).await
-                                };
-
-                                match entity
-                                {
-                                    Ok(adopted) => {
-                                        let entity_id = {
-                                            self.world.write().spawn((
-                                                adopted,
-                                                scene_entity.transform,
-                                                ModelProperties::default(),
-                                            ))
-                                        };
-
-
-                                        self.selected_entity = Some(entity_id);
-                                        log::debug!(
-                                            "Successfully paste-spawned {} with ID {:?}",
-                                            scene_entity.label,
-                                            entity_id
-                                        );
-
-                                        success_without_console!("Paste!");
-                                        self.signal = Signal::Copy(scene_entity.clone());
-                                    }
-                                    Err(e) => {
-                                        warn!("Failed to paste-spawn {}: {}", scene_entity.label, e);
-                                    }
-                                }
-                            }
-                            None => {
-                                fatal!(
-                                    "Unable to convert resource reference [{}] to project related path",
-                                    reference
-                                );
-                                self.signal = Signal::None;
-                            }
-                        };
-                    } else {
-                        fatal!("Project path is not set");
-                        self.signal = Signal::None;
-                    }
-                }
-                dropbear_engine::utils::ResourceReferenceType::Bytes(bytes) => {
-                    let model = match Model::load_from_memory(
-                        graphics.shared.clone(),
-                        bytes,
-                        Some(&scene_entity.label),
-                    )
-                    .await
-                    {
-                        Ok(v) => v,
-                        Err(e) => {
-                            fatal!("Unable to load from memory: {}", e);
-                            self.signal = Signal::None;
-                            return;
-                        }
-                    };
-                    let adopted = AdoptedEntity::adopt(graphics.shared.clone(), model).await;
-
-                    let entity_id = {
-                        self.world.write().spawn((
-                            adopted,
-                            scene_entity.transform,
-                            ModelProperties::default(),
-                        ))
-                    };
-
-                    self.selected_entity = Some(entity_id);
-                    log::debug!(
-                        "Successfully paste-spawned {} with ID {:?}",
-                        scene_entity.label,
-                        entity_id
-                    );
-
-                    success_without_console!("Paste!");
-                    self.signal = Signal::Copy(scene_entity.clone());
-                }
-                _ => {
-                    warn!("Unable to copy, not of bytes or path");
-                    self.signal = Signal::None;
-                    return;
-                }
-            },
-            Signal::Delete => {
-                if let Some(sel_e) = &self.selected_entity {
-                    {
-                        let is_viewport_cam = if let Ok(mut q) = self.world.read()
-                            .query_one::<&CameraComponent>(*sel_e)
-                        {
-                            if let Some(c) = q.get() {
-                                if matches!(c.camera_type, CameraType::Debug) {
-                                    true
-                                } else {
-                                    false
-                                }
-                            } else {
-                                false
-                            }
-                        } else {
-                            false
-                        };
-                        if is_viewport_cam {
-                            warn!("You can't delete the viewport camera");
-                            self.signal = Signal::None;
-                        } else {
-                            match self.world.write().despawn(*sel_e) {
-                                Ok(_) => {
-                                    info!("Decimated entity");
-                                    self.signal = Signal::None;
-                                }
-                                Err(e) => {
-                                    warn!("Failed to delete entity: {}", e);
-                                    self.signal = Signal::None;
-                                }
-                            }
-                            // println!("is world still locked here [{}]: {}", file!(), self.world.is_locked_exclusive())
-                        }
-                    }
-                }
-            }
-            Signal::Undo => {
-                {
-                    if let Some(action) = self.undo_stack.pop() {
-                        match action.undo(self.world.clone()) {
-                            Ok(_) => {
-                                info!("Undid action");
-                            }
-                            Err(e) => {
-                                warn!("Failed to undo action: {}", e);
-                            }
-                        }
-                    } else {
-                        warn_without_console!("Nothing to undo");
-                        log::debug!("No undoable actions in stack");
-                    }
-                    self.signal = Signal::None;
-                }
-            }
-            Signal::None => {}
-            Signal::Copy(_) => {}
-            Signal::ScriptAction(action) => match action {
-                ScriptAction::AttachScript {
-                    script_path,
-                    script_name,
-                } => {
-                    if let Some(selected_entity) = self.selected_entity {
-                        match scripting::move_script_to_src(script_path) {
-                            Ok(moved_path) => {
-                                let new_script = ScriptComponent {
-                                    name: script_name.clone(),
-                                    path: moved_path.clone(),
-                                };
-
-                                let replaced = {
-                                    let world = self.world.read();
-                                    if let Ok(mut sc) = world.get::<&mut ScriptComponent>(selected_entity) {
-                                        sc.name = new_script.name.clone();
-                                        sc.path = new_script.path.clone();
-                                        true
-                                    } else {
-                                        false
-                                    }
-                                };
-
-                                if !replaced {
-                                    match scripting::attach_script_to_entity(
-                                        self.world.clone(),
-                                        selected_entity,
-                                        new_script.clone(),
-                                    ) {
-                                        Ok(_) => {
-                                        }
-                                        Err(e) => {
-                                            fatal!(
-                                                "Failed to attach script to entity {:?}: {}",
-                                                selected_entity,
-                                                e
-                                            );
-                                            self.signal = Signal::None;
-                                            return;
-                                        }
-                                    }
-                                }
-
-                                {
-                                    if let Err(e) = scripting::convert_entity_to_group(
-                                        self.world.clone(),
-                                        selected_entity,
-                                    ) {
-                                        log::warn!("convert_entity_to_group failed (non-fatal): {}", e);
-                                    }
-                                }
-
-                                success!(
-                                    "{} script '{}' at {} to entity {:?}",
-                                    if replaced { "Reattached" } else { "Attached" },
-                                    script_name,
-                                    moved_path.display(),
-                                    selected_entity
-                                );
-                            }
-                            Err(e) => {
-                                fatal!("Move failed: {}", e);
-                            }
-                        }
-                    } else {
-                        fatal!("AttachScript requested but no entity is selected");
-                    }
-
-                    self.signal = Signal::None;
-                }
-                ScriptAction::CreateAndAttachScript {
-                    script_path,
-                    script_name,
-                } => {
-                    if let Some(selected_entity) = self.selected_entity {
-                        let new_script = ScriptComponent {
-                            name: script_name.clone(),
-                            path: script_path.clone(),
-                        };
-
-                        let replaced = {
-                            let world = self.world.read();
-                            if let Ok(mut sc) = world.get::<&mut ScriptComponent>(selected_entity) {
-                                sc.name = new_script.name.clone();
-                                sc.path = new_script.path.clone();
-                                true
-                            } else {
-                                false
-                            }
-                        };
-
-                        if !replaced {
-                            match scripting::attach_script_to_entity(
-                                self.world.clone(),
-                                selected_entity,
-                                new_script.clone(),
-                            ) {
-                                Ok(_) => {
-                                }
-                                Err(e) => {
-                                    fatal!("Failed to attach new script: {}", e);
-                                    self.signal = Signal::None;
-                                    return;
-                                }
-                            }
-                        }
-
-                        {
-                            if let Err(e) = scripting::convert_entity_to_group(
-                                self.world.clone(),
-                                selected_entity,
-                            ) {
-                                log::warn!("convert_entity_to_group failed (non-fatal): {}", e);
-                            }
-                        }
-
-                        success!(
-                            "{} new script '{}' at {} to entity {:?}",
-                            if replaced { "Replaced" } else { "Attached" },
-                            script_name,
-                            script_path.display(),
-                            selected_entity
-                        );
-                    } else {
-                        warn_without_console!("No selected entity to attach new script");
-                        log::warn!("CreateAndAttachScript requested but no entity is selected");
-                    }
-                    self.signal = Signal::None;
-                }
-                ScriptAction::RemoveScript => {
-                    if let Some(selected_entity) = self.selected_entity {
-                        let mut success = false;
-                        let mut comp = ScriptComponent::default();
-                        {
-                            if let Ok(script) = self.world.write()
-                                .remove_one::<ScriptComponent>(selected_entity)
-                            {
-                                success!("Removed script from entity {:?}", selected_entity);
-                                success = true;
-                                comp = script.clone();
-                            } else {
-                                warn!("No script component found on entity {:?}", selected_entity);
-                            }
-                        }
-
-                        if success {
-                            if let Err(e) = scripting::convert_entity_to_group(
-                                self.world.clone(),
-                                selected_entity,
-                            ) {
-                                log::warn!("convert_entity_to_group failed (non-fatal): {}", e);
-                            }
-                            log::debug!("Pushing remove component to undo stack");
-                            UndoableAction::push_to_undo(
-                                &mut self.undo_stack,
-                                UndoableAction::RemoveComponent(
-                                    selected_entity,
-                                    ComponentType::Script(comp),
-                                ),
-                            );
-                        }
-                    } else {
-                        warn!("No entity selected to remove script from");
-                    }
-
-                    self.signal = Signal::None;
-                }
-                ScriptAction::EditScript => {
-                    if let Some(selected_entity) = self.selected_entity {
-                        let script_opt = {
-                            let world = self.world.read();
-                            if let Ok(mut q) = world.query_one::<&ScriptComponent>(selected_entity) {
-                                q.get().cloned()
-                            } else {
-                                None
-                            }
-                        };
-
-                        if let Some(script) = script_opt {
-                            match open::that(script.path.clone()) {
-                                Ok(()) => {
-                                    success!("Opened {}", script.name)
-                                }
-                                Err(e) => {
-                                    warn!("Error while opening {}: {}", script.name, e);
-                                }
-                            }
-                        } else {
-                            warn!("No script component found on entity {:?}", selected_entity);
-                        }
-                    } else {
-                        warn!("No entity selected to edit script");
-                    }
-                    self.signal = Signal::None;
-                }
-            },
-            Signal::Play => {
-                let has_player_camera_target = self
-                    .world.read()
-                    .query::<(&Camera, &CameraComponent, &CameraFollowTarget)>()
-                    .iter()
-                    .any(|(_, (_, comp, _))| matches!(comp.camera_type, CameraType::Player));
-
-                if has_player_camera_target {
-                    if let Err(e) = self.create_backup() {
-                        fatal!("Failed to create play mode backup: {}", e);
-                        self.signal = Signal::None;
-                        return;
-                    }
-
-                    self.editor_state = EditorState::Playing;
-
-                    self.switch_to_player_camera();
-
-                    let mut script_entities = Vec::new();
-                    {
-                        for (entity_id, script) in self.world.read()
-                            .query::<&ScriptComponent>()
-                            .iter()
-                        {
-                            script_entities.push((entity_id, script.clone()));
-                        }
-                    }
-
-                    for (entity_id, script) in script_entities {
-                        log::debug!(
-                            "Initialising entity script [{}] from path: {}",
-                            script.name,
-                            script.path.display()
-                        );
-
-                        let bytes = match tokio::fs::read_to_string(&script.path).await {
-                            Ok(val) => val,
-                            Err(e) => {
-                                fatal!(
-                                    "Unable to read script {} to bytes because {}",
-                                    &script.path.display(),
-                                    e
-                                );
-                                self.signal = Signal::None;
-                                return;
-                            }
-                        };
-
-                        match self.script_manager.load_script(
-                            &script
-                                .path
-                                .file_name()
-                                .unwrap()
-                                .to_string_lossy()
-                                .to_string(),
-                            bytes,
-                        ) {
-                            Ok(script_name) => {
-                                if let Err(e) = self.script_manager.init_entity_script(
-                                    entity_id,
-                                    &script_name,
-                                    self.world.clone(),
-                                    &self.input_state,
-                                ) {
-                                    log::warn!(
-                                        "Failed to initialise script '{}' for entity {:?}: {}",
-                                        script.name,
-                                        entity_id,
-                                        e
-                                    );
-                                    self.signal = Signal::StopPlaying;
-                                } else {
-                                    success_without_console!(
-                                        "You are in play mode now! Press Escape to exit"
-                                    );
-                                    log::info!("You are in play mode now! Press Escape to exit");
-                                }
-                            }
-                            Err(e) => {
-                                // todo: proper error menu
-                                fatal!("Failed to load script '{}': {}", script.name, e);
-                                self.signal = Signal::StopPlaying;
-                            }
-                        }
-                    }
-                } else {
-                    fatal!("Unable to build: Player camera not attached to an entity");
-                }
-
-                self.signal = Signal::None;
-            }
-            Signal::StopPlaying => {
-                if let Err(e) = self.restore() {
-                    warn!("Failed to restore from play mode backup: {}", e);
-                    log::warn!("Failed to restore scene state: {}", e);
-                }
-
-                self.editor_state = EditorState::Editing;
-
-                self.switch_to_debug_camera();
-
-                // already kills itself
-                // for (entity_id, _) in Arc::get_mut(&mut self.world).unwrap().query::<&ScriptComponent>().iter() {
-                //     self.script_manager.remove_entity_script(entity_id);
-                // }
-
-                success!("Exited play mode");
-                log::info!("Back to the editor you go...");
-
-                self.signal = Signal::None;
-            }
-            Signal::CameraAction(action) => match action {
-                CameraAction::SetPlayerTarget { entity, offset } => {
-                    let player_camera = self
-                        .world.read()
-                        .query::<(&Camera, &CameraComponent)>()
-                        .iter()
-                        .find_map(|(e, (_, comp))| {
-                            if matches!(comp.camera_type, CameraType::Player) {
-                                Some(e)
-                            } else {
-                                None
-                            }
-                        });
-
-                    if let Some(camera_entity) = player_camera {
-                        let mut follow_target = (false, CameraFollowTarget::default());
-                        if let Ok(mut query) = self.world.read()
-                            .query_one::<&AdoptedEntity>(*entity)
-                        {
-                            if let Some(adopted) = query.get() {
-                                follow_target = (
-                                    true,
-                                    CameraFollowTarget {
-                                        follow_target: adopted.model.label.to_string(),
-                                        offset: *offset,
-                                    },
-                                );
-                            }
-                        }
-
-                        {
-                            if follow_target.0 {
-                                let _ = self.world.write()
-                                    .insert_one(camera_entity, follow_target);
-                                info!("Set player camera target to entity {:?}", entity);
-                            }
-                        }
-                    }
-                    self.signal = Signal::None;
-                }
-                CameraAction::ClearPlayerTarget => {
-                    let player_camera = self
-                        .world.read()
-                        .query::<(&Camera, &CameraComponent)>()
-                        .iter()
-                        .find_map(|(e, (_, comp))| {
-                            if matches!(comp.camera_type, CameraType::Player) {
-                                Some(e)
-                            } else {
-                                None
-                            }
-                        });
-
-                    if let Some(camera_entity) = player_camera {
-                        {
-                            let _ = self.world.write()
-                                .remove_one::<CameraFollowTarget>(camera_entity);
-                        }
-                    }
-                    info!("Cleared player camera target");
-                    self.signal = Signal::None;
-                }
-            },
-            Signal::AddComponent(entity, e_type) => {
-                match e_type {
-                    EntityType::Entity => {
-                        if let Ok(mut q) = self.world.read()
-                            .query_one::<&AdoptedEntity>(*entity)
-                        {
-                            if let Some(e) = q.get() {
-                                let mut local_signal: Option<Signal> = None;
-                                let label = e.model.label.clone();
-                                let mut show = true;
-                                egui::Window::new(format!("Add component for {}", label))
-                                    .title_bar(true)
-                                    .open(&mut show)
-                                    .scroll([false, true])
-                                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                                    .enabled(true)
-                                    .show(&graphics.shared.get_egui_context(), |ui| {
-                                        if ui
-                                            .add_sized(
-                                                [ui.available_width(), 30.0],
-                                                egui::Button::new("Scripting"),
-                                            )
-                                            .clicked()
-                                        {
-                                            log::debug!(
-                                            "Adding scripting component to entity [{}]",
-                                            label
-                                        );
-                                            {
-                                                if let Err(e) = self.world.write()
-                                                    .insert_one(*entity, ScriptComponent::default())
-                                                {
-                                                    warn!(
-                                                "Failed to add scripting component to entity: {}",
-                                                e
-                                            );
-                                                } else {
-                                                    success!("Added the scripting component");
-                                                }
-                                            }
-                                            local_signal = Some(Signal::None);
-                                        }
-                                        if ui
-                                            .add_sized(
-                                                [ui.available_width(), 30.0],
-                                                egui::Button::new("Camera"),
-                                            )
-                                            .clicked()
-                                        {
-                                            log::debug!(
-                                            "Adding camera component to entity [{}]",
-                                            label
-                                        );
-
-                                            let has_camera = self.world.read()
-                                                .query_one::<(&Camera, &CameraComponent)>(*entity)
-                                                .is_ok();
-
-                                            if has_camera {
-                                                warn!(
-                                                "Entity [{}] already has a camera component",
-                                                label
-                                            );
-                                            } else {
-                                                let camera = Camera::predetermined(
-                                                    graphics.shared.clone(),
-                                                    Some(&format!("{} Camera", label)),
-                                                );
-                                                let component = CameraComponent::new();
-
-                                                {
-                                                    if let Err(e) = self.world.write()
-                                                        .insert(*entity, (camera, component))
-                                                    {
-                                                        warn!(
-                                                    "Failed to add camera component to entity: {}",
-                                                    e
-                                                );
-                                                    } else {
-                                                        success!("Added the camera component");
-                                                    }
-                                                }
-                                            }
-                                            local_signal = Some(Signal::None);
-                                        }
-                                    });
-                                if !show {
-                                    self.signal = Signal::None;
-                                }
-                                if let Some(signal) = local_signal {
-                                    self.signal = signal
-                                }
-                            }
-                        } else {
-                            log_once::warn_once!(
-                                "Failed to add component to entity: no entity component found"
-                            );
-                        }
-                    }
-                    EntityType::Light => {
-                        {
-                            if let Ok(mut q) = self.world.read()
-                                .query_one::<&Light>(*entity)
-                            {
-                                if let Some(light) = q.get() {
-                                    let mut show = true;
-                                    egui::Window::new(format!("Add component for {}", light.label))
-                                        .scroll([false, true])
-                                        .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                                        .enabled(true)
-                                        .open(&mut show)
-                                        .title_bar(true)
-                                        .show(&graphics.shared.get_egui_context(), |ui| {
-                                            if ui
-                                                .add_sized(
-                                                    [ui.available_width(), 30.0],
-                                                    egui::Button::new("Scripting"),
-                                                )
-                                                .clicked()
-                                            {
-                                                log::debug!(
-                                            "Adding scripting component to light [{}]",
-                                            light.label
-                                        );
-
-                                                success!(
-                                            "Added the scripting component to light [{}]",
-                                            light.label
-                                        );
-                                                self.signal = Signal::None;
-                                            }
-                                        });
-                                    if !show {
-                                        self.signal = Signal::None;
-                                    }
-                                }
-                            } else {
-                                log_once::warn_once!(
-                                "Failed to add component to light: no light component found"
-                            );
-                            }
-                        }
-                    }
-                    EntityType::Camera => {
-                        {
-                            if let Ok(mut q) = self.world.write()
-                                .query_one::<(&Camera, &CameraComponent)>(*entity)
-                            {
-                                if let Some((cam, _comp)) = q.get() {
-                                    let mut show = true;
-                                    egui::Window::new(format!("Add component for {}", cam.label))
-                                        .scroll([false, true])
-                                        .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                                        .enabled(true)
-                                        .open(&mut show)
-                                        .title_bar(true)
-                                        .show(&graphics.shared.get_egui_context(), |ui| {
-                                            egui_extras::install_image_loaders(ui.ctx());
-                                            ui.add(Image::from_bytes(
-                                                "bytes://theres_nothing.jpg",
-                                                include_bytes!("../../../resources/theres_nothing.jpg"),
-                                            ));
-                                            ui.label("Theres nothing...");
-                                            // // scripting
-                                            // if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Scripting")).clicked() {
-                                            //     log::debug!("Adding scripting component to camera [{}]", cam.label);
-
-                                            //     success!("Added the scripting component to camera [{}]", cam.label);
-                                            //     self.signal = Signal::None;
-                                            // }
-                                        });
-                                    if !show {
-                                        self.signal = Signal::None;
-                                    }
-                                }
-                            } else {
-                                log_once::warn_once!(
-                                "Failed to add component to light: no light component found"
-                            );
-                            }
-                        }
-                    }
-                }
-            }
-            Signal::RemoveComponent(entity, c_type) =>
-            {match c_type {
-                ComponentType::Script(_) => {
-                    match self.world.write()
-                        .remove_one::<ScriptComponent>(*entity)
-                    {
-                        Ok(component) => {
-                            success!("Removed script component from entity {:?}", entity);
-                            UndoableAction::push_to_undo(
-                                &mut self.undo_stack,
-                                UndoableAction::RemoveComponent(
-                                    *entity,
-                                    ComponentType::Script(component),
-                                ),
-                            );
-                        }
-                        Err(e) => {
-                            warn!("Failed to remove script component from entity: {}", e);
-                        }
-                    };
-                    self.signal = Signal::None;
-                }
-                ComponentType::Camera(_, _, follow) => {
-                    if let Some(_) = follow {
-                        match self.world.write().remove::<(
-                            Camera,
-                            CameraComponent,
-                            CameraFollowTarget,
-                        )>(
-                            *entity
-                        ) {
-                            Ok(component) => {
-                                success!("Removed camera component from entity {:?}", entity);
-                                UndoableAction::push_to_undo(
-                                    &mut self.undo_stack,
-                                    UndoableAction::RemoveComponent(
-                                        *entity,
-                                        ComponentType::Camera(
-                                            component.0,
-                                            component.1,
-                                            Some(component.2),
-                                        ),
-                                    ),
-                                );
-                            }
-                            Err(e) => {
-                                warn!("Failed to remove camera component from entity: {}", e);
-                            }
-                        };
-                    } else {
-                        match self.world.write()
-                            .remove::<(Camera, CameraComponent)>(*entity)
-                        {
-                            Ok(component) => {
-                                success!("Removed camera component from entity {:?}", entity);
-                                UndoableAction::push_to_undo(
-                                    &mut self.undo_stack,
-                                    UndoableAction::RemoveComponent(
-                                        *entity,
-                                        ComponentType::Camera(component.0, component.1, None),
-                                    ),
-                                );
-                            }
-                            Err(e) => {
-                                warn!("Failed to remove script component from entity: {}", e);
-                            }
-                        };
-                    }
-                }
-            }},
-            Signal::CreateEntity => {
-                let mut show = true;
-                egui::Window::new("Add Entity")
-                    .scroll([false, true])
-                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                    .enabled(true)
-                    .open(&mut show)
-                    .title_bar(true)
-                    .show(&graphics.shared.get_egui_context(), |ui| {
-                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Model")).clicked() {
-                            log::debug!("Creating new model");
-                            warn!("Instead of using the `Add Entity` window, double click on the imported model in the asset \n\
-                            viewer to import a new model, then tweak the settings to how you wish after!");
-                            self.signal = Signal::None;
-                        }
-
-                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Light")).clicked() {
-                            log::debug!("Creating new lighting");
-                            self.signal = Signal::Spawn(PendingSpawn2::CreateLight);
-                        }
-
-                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Plane")).clicked() {
-                            log::debug!("Creating new plane");
-                            self.signal = Signal::Spawn(PendingSpawn2::CreatePlane);
-                        }
-
-                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Cube")).clicked() {
-                            log::debug!("Creating new cube");
-                            self.signal = Signal::Spawn(PendingSpawn2::CreateCube);
-                        }
-
-                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Camera")).clicked() {
-                            log::debug!("Creating new cube");
-                            self.signal = Signal::Spawn(PendingSpawn2::CreateCamera);
-                        }
-                    });
-                if !show {
-                    self.signal = Signal::None;
-                }
-            }
-            Signal::LogEntities => {
-                log::debug!("====================");
-                let mut counter = 0;
-                for entity in self.world.read().iter() {
-                    if let Some(entity) = entity.get::<&AdoptedEntity>() {
-                        log::info!("Model: {:?}", entity.model.label);
-                        log::info!("  |-> Using model: {:?}", entity.model.id);
-                    }
-
-                    if let Some(entity) = entity.get::<&Light>() {
-                        log::info!("Light: {:?}", entity.cube_model.label);
-                        log::info!("  |-> Using model: {:?}", entity.cube_model.id);
-                    }
-
-                    if let Some(_) = entity.get::<&Camera>() {
-                        log::info!("Camera");
-                    }
-                    counter += 1;
-                }
-                log::debug!("====================");
-                info!("Total entity count: {}", counter);
-                self.signal = Signal::None;
-            }
-            Signal::Spawn(entity_type) => {
-                match entity_type {
-                    crate::editor::PendingSpawn2::CreateLight => {
-                        let transform = Transform::new();
-                        let component = LightComponent::default();
-                        let light = Light::new(
-                            graphics.shared.clone(),
-                            &component,
-                            &transform,
-                            Some("Light"),
-                        )
-                        .await;
-                        {
-                            self.world.write()
-                                .spawn((light, component, transform));
-                        }
-                        success!("Created new light");
-                    }
-                    crate::editor::PendingSpawn2::CreatePlane => {
-                        let plane = PlaneBuilder::new()
-                            .with_size(500.0, 200.0)
-                            .build(graphics.shared.clone(), PROTO_TEXTURE, Some("Plane"))
-                            .await
-                            .unwrap();
-
-                        let transform = Transform::new();
-                        let mut props = ModelProperties::new();
-                        props
-                            .custom_properties
-                            .insert("width".to_string(), Value::Float(500.0));
-                        props
-                            .custom_properties
-                            .insert("height".to_string(), Value::Float(200.0));
-                        props
-                            .custom_properties
-                            .insert("tiles_x".to_string(), Value::Int(500));
-                        props
-                            .custom_properties
-                            .insert("tiles_z".to_string(), Value::Int(200));
-                        {
-                            self.world.write()
-                                .spawn((plane, transform, props));
-                        }
-                        success!("Created new plane");
-                    }
-                    crate::editor::PendingSpawn2::CreateCube => {
-                        let model = Model::load_from_memory(
-                            graphics.shared.clone(),
-                            include_bytes!("../../../resources/cube.glb"),
-                            Some("Cube"),
-                        )
-                        .await;
-                        match model {
-                            Ok(model) => {
-                                let cube = AdoptedEntity::adopt(
-                                    graphics.shared.clone(),
-                                    model,
-                                    // Some("Cube")
-                                )
-                                .await;
-                                {
-                                    self.world.write().spawn((
-                                        cube,
-                                        Transform::new(),
-                                        ModelProperties::new(),
-                                    ));
-                                }
-                            }
-                            Err(e) => {
-                                fatal!("Failed to load cube model: {}", e);
-                            }
-                        }
-                        success!("Created new cube");
-                    }
-                    crate::editor::PendingSpawn2::CreateCamera => {
-                        let camera = Camera::predetermined(graphics.shared.clone(), None);
-                        let component = CameraComponent::new();
-                        {
-                            self.world.write()
-                                .spawn((camera, component));
-                        }
-                        success!("Created new camera");
-                    }
-                }
-                self.signal = Signal::None;
+        match self.run_signal(graphics.shared.clone()) {
+            Ok(_) => {}
+            Err(e) => {
+                fatal!("{}", e);
             }
         }
 
@@ -1177,19 +206,16 @@ impl Scene for Editor {
         {
             let active_cam = self.active_camera.lock();
             if let Some(active_camera) = *active_cam {
-                let world = self.world.read();
-                if let Ok(mut query) = world.query_one::<&mut Camera>(active_camera) {
-                    if let Some(camera) = query.get() {
+                if let Ok(mut query) = self.world.query_one::<&mut Camera>(active_camera)
+                    && let Some(camera) = query.get() {
                         camera.aspect = new_aspect;
                     }
-                }
             }
 
         }
 
         let camera_follow_data: Vec<(Entity, String, glam::Vec3)> = {
-            let world = self.world.read();
-            world
+            self.world
                 .query::<(&Camera, &CameraComponent, Option<&CameraFollowTarget>)>()
                 .iter()
                 .filter_map(|(entity_id, (_, _, follow_target))| {
@@ -1207,8 +233,7 @@ impl Scene for Editor {
 
         for (camera_entity, target_label, offset) in camera_follow_data {
             let target_position = {
-                let world = self.world.read();
-                world
+                self.world
                     .query::<(&AdoptedEntity, &Transform)>()
                     .iter()
                     .find_map(|(_, (adopted, transform))| {
@@ -1222,20 +247,17 @@ impl Scene for Editor {
 
 
             if let Some(pos) = target_position {
-                let world = self.world.read();
-                if let Ok(mut query) = world.query_one::<&mut Camera>(camera_entity) {
-                    if let Some(camera) = query.get() {
+                if let Ok(mut query) = self.world.query_one::<&mut Camera>(camera_entity)
+                    && let Some(camera) = query.get() {
                         camera.eye = pos + offset.as_dvec3();
                         camera.target = pos;
                     }
-                }
             }
 
         }
 
         {
-            let world = self.world.read();
-            for (_entity_id, (camera, component)) in world
+            for (_entity_id, (camera, component)) in self.world
                 .query::<(&mut Camera, &mut CameraComponent)>()
                 .iter()
             {
@@ -1246,8 +268,7 @@ impl Scene for Editor {
 
         {
             {
-                let mut world = self.world.write();
-                let query = world
+                let query = self.world
                     .query_mut::<(&mut AdoptedEntity, &Transform)>();
                 for (_, (entity, transform)) in query {
                     entity.update(graphics.shared.clone(), transform);
@@ -1256,9 +277,8 @@ impl Scene for Editor {
 
 
             {
-                let mut world = self.world.write();
                 let light_query =
-                    world
+                    self.world
                         .query_mut::<(&mut LightComponent, &Transform, &mut Light)>();
                 for (_, (light_component, transform, light)) in light_query {
                     light.update(light_component, transform);
@@ -1268,22 +288,20 @@ impl Scene for Editor {
         }
 
         {
-            let mut world = self.world.read();
             self.light_manager.update(
                 graphics.shared.clone(),
-                &mut world,
+                &self.world,
             );
         }
-        
 
         if self.dep_installer.is_installing {
             self.dep_installer
-                .show_installation_window(&mut graphics.shared.get_egui_context());
+                .show_installation_window(&graphics.shared.get_egui_context());
         }
         self.dep_installer.update_progress();
     }
 
-    async fn render<'a>(&mut self, graphics: &mut RenderContext<'a>) {
+    fn render(&mut self, graphics: &mut RenderContext) {
         // cornflower blue
         let color = Color {
             r: 100.0 / 255.0,
@@ -1292,10 +310,10 @@ impl Scene for Editor {
             a: 1.0,
         };
 
-        self.color = color.clone();
-        self.size = graphics.shared.viewport_texture.size.clone();
+        self.color = color;
+        self.size = graphics.shared.viewport_texture.size;
         self.texture_id = Some(*graphics.shared.texture_id.clone());
-        { self.show_ui(&graphics.shared.get_egui_context()).await; }
+        { self.show_ui(&graphics.shared.get_egui_context()); }
 
         self.window = Some(graphics.shared.window.clone());
         logging::render(&graphics.shared.get_egui_context());
@@ -1303,13 +321,8 @@ impl Scene for Editor {
             log_once::debug_once!("Found render pipeline");
             if let Some(active_camera) = *self.active_camera.lock() {
                 let cam = {
-                    let world = self.world.read();
-                    if let Ok(mut query) = world.query_one::<&Camera>(active_camera) {
-                        if let Some(camera) = query.get() {
-                            Some(camera.clone())
-                        } else {
-                            None
-                        }
+                    if let Ok(mut query) = self.world.query_one::<&Camera>(active_camera) {
+                        query.get().cloned()
                     } else {
                         None
                     }
@@ -1317,9 +330,8 @@ impl Scene for Editor {
 
                 if let Some(camera) = cam {
                     let lights = {
-                        let world = self.world.read();
                         let mut lights = Vec::new();
-                        let mut light_query = world.query::<(&Light, &LightComponent)>();
+                        let mut light_query = self.world.query::<(&Light, &LightComponent)>();
                         for (_, (light, comp)) in light_query.iter() {
                             lights.push((light.clone(), comp.clone()));
                         }
@@ -1328,9 +340,8 @@ impl Scene for Editor {
 
 
                     let entities = {
-                        let world = self.world.read();
                         let mut entities = Vec::new();
-                        let mut entity_query = world.query::<&AdoptedEntity>();
+                        let mut entity_query = self.world.query::<&AdoptedEntity>();
                         for (_, entity) in entity_query.iter() {
                             entities.push(entity.clone());
                         }
@@ -1363,7 +374,7 @@ impl Scene for Editor {
                         let instance_raw = entity.instance.to_raw();
                         model_batches
                             .entry(model_ptr)
-                            .or_insert(Vec::new())
+                            .or_default()
                             .push(instance_raw);
                     }
 
diff --git a/eucalyptus-editor/src/main.rs b/eucalyptus-editor/src/main.rs
index a8fa5c0..fd27176 100644
--- a/eucalyptus-editor/src/main.rs
+++ b/eucalyptus-editor/src/main.rs
@@ -5,11 +5,15 @@ mod debug;
 mod editor;
 mod menu;
 mod utils;
+mod spawn;
+mod signal;
 
 use clap::{Arg, Command};
-use std::{cell::RefCell, fs, path::PathBuf, rc::Rc};
-
-use dropbear_engine::{WindowConfiguration, scene};
+use dropbear_engine::{scene, WindowConfiguration};
+use std::{fs, path::PathBuf, rc::Rc};
+use std::sync::Arc;
+use parking_lot::RwLock;
+use dropbear_engine::future::FutureQueue;
 
 pub const APP_INFO: app_dirs2::AppInfo = app_dirs2::AppInfo {
     name: "Eucalyptus",
@@ -114,11 +118,13 @@ async fn main() -> anyhow::Result<()> {
                 max_fps: dropbear_engine::App::NO_FPS_CAP,
                 app_info: APP_INFO,
             };
+            
+            let future_queue = Arc::new(FutureQueue::new());
 
-            let main_menu = Rc::new(RefCell::new(crate::menu::MainMenu::new()));
-            let editor = Rc::new(RefCell::new(crate::editor::Editor::new()));
+            let main_menu = Rc::new(RwLock::new(menu::MainMenu::new()));
+            let editor = Rc::new(RwLock::new(editor::Editor::new()));
 
-            let _app = dropbear_engine::run_app!(config, |mut scene_manager, mut input_manager| {
+            dropbear_engine::run_app!(config, Some(future_queue), |mut scene_manager, mut input_manager| {
                 scene::add_scene_with_input(
                     &mut scene_manager,
                     &mut input_manager,
@@ -136,8 +142,7 @@ async fn main() -> anyhow::Result<()> {
 
                 (scene_manager, input_manager)
             })
-            .await
-            .unwrap();
+            .await?;
         }
         _ => unreachable!(),
     }
@@ -152,13 +157,11 @@ fn find_eucp_file() -> Result<PathBuf, String> {
     let mut eucp_files = Vec::new();
 
     for entry in entries {
-        if let Ok(entry) = entry {
-            if let Some(file_name) = entry.file_name().to_str() {
-                if file_name.ends_with(".eucp") {
+        if let Ok(entry) = entry
+            && let Some(file_name) = entry.file_name().to_str()
+                && file_name.ends_with(".eucp") {
                     eucp_files.push(entry.path());
                 }
-            }
-        }
     }
 
     match eucp_files.len() {
diff --git a/eucalyptus-editor/src/menu.rs b/eucalyptus-editor/src/menu.rs
index 7caa31b..fd8e9e2 100644
--- a/eucalyptus-editor/src/menu.rs
+++ b/eucalyptus-editor/src/menu.rs
@@ -1,52 +1,56 @@
 use std::{
     fs,
-    sync::mpsc::{self, Receiver},
+    path::PathBuf,
 };
-
+use std::sync::Arc;
 use anyhow::anyhow;
 use dropbear_engine::{
     graphics::RenderContext,
     input::{Controller, Keyboard, Mouse},
     scene::{Scene, SceneCommand},
+    future::{FutureHandle, FutureQueue},
 };
 use egui::{self, FontId, Frame, RichText};
 use egui_toast_fork::{ToastOptions, Toasts};
-use gilrs;
 use git2::Repository;
 use log::{self, debug};
+use rfd::FileDialog; // ← Sync version — no async needed
 use winit::{
     dpi::PhysicalPosition, event::MouseButton, event_loop::ActiveEventLoop, keyboard::KeyCode,
 };
-
 use eucalyptus_core::states::{PROJECT, ProjectConfig};
+use tokio::sync::watch;
+
+#[derive(Debug, Clone)]
+pub enum ProjectProgress {
+    Step {
+        progress: f32,
+        message: String,
+    },
+    Error(String),
+    Done,
+}
 
 #[derive(Default)]
 pub struct MainMenu {
     scene_command: SceneCommand,
     show_new_project: bool,
     project_name: String,
-    project_path: Option<std::path::PathBuf>,
+    project_path: Option<PathBuf>,
     project_error: Option<Vec<String>>,
 
-    progress_rx: Option<Receiver<ProjectProgress>>,
-
+    project_progress_rx: Option<watch::Receiver<ProjectProgress>>,
     show_progress: bool,
     progress: f32,
     progress_message: String,
+
+    // ❌ REMOVED: file_dialog: Option<FutureHandle>,
+    project_creation_handle: Option<FutureHandle>, // ← Keep — project creation is async
+
     toast: Toasts,
     is_in_file_dialogue: bool,
 }
 
-pub enum ProjectProgress {
-    Step {
-        progress: f32,
-        message: String,
-    },
-    #[allow(dead_code)]
-    Error(String),
-    Done,
-}
-
 impl MainMenu {
     pub fn new() -> Self {
         Self {
@@ -58,111 +62,150 @@ impl MainMenu {
         }
     }
 
-    fn start_project_creation(&mut self) {
-        let (tx, rx) = mpsc::channel();
+    fn start_project_creation(&mut self, queue: Arc<FutureQueue>) {
         let project_name = self.project_name.clone();
         let project_path = self.project_path.clone();
 
-        self.progress_rx = Some(rx);
+        let (progress_tx, progress_rx) = watch::channel(ProjectProgress::Step {
+            progress: 0.0,
+            message: "Starting project creation...".to_string(),
+        });
+
+        self.project_progress_rx = Some(progress_rx);
         self.show_progress = true;
         self.progress = 0.0;
-        self.progress_message = "Starting project creation...".to_string();
 
-        std::thread::spawn(move || {
+        let handle = queue.push(async move {
             let mut errors = Vec::new();
             let folders = [
-                ("git", 0.1, "Creating a git folder..."),
+                ("git", 0.1, "Initializing git repository..."),
                 ("src", 0.2, "Creating src folder..."),
                 ("resources/models", 0.3, "Creating models folder..."),
-                ("resources/shaders", 0.4, "Creating shader folder..."),
+                ("resources/shaders", 0.4, "Creating shaders folder..."),
                 ("resources/textures", 0.5, "Creating textures folder..."),
-                ("src2", 0.6, "Creating project config file..."),
-                ("scenes", 0.7, "Creating the scenes folder"),
+                ("src2", 0.6, "Generating project config..."),
+                ("scenes", 0.7, "Creating scenes folder..."),
             ];
 
             if let Some(path) = &project_path {
                 for (folder, progress, message) in folders {
-                    tx.send(ProjectProgress::Step {
+                    let _ = progress_tx.send(ProjectProgress::Step {
                         progress,
                         message: message.to_string(),
-                    })
-                    .ok();
+                    });
 
                     let full_path = path.join(folder);
-                    let result: anyhow::Result<()> = if folder == "src" {
-                        if !full_path.exists() {
-                            fs::create_dir(&full_path)
-                                .map_err(|e| anyhow::anyhow!(e))
-                                .map(|_| ())
-                        } else {
-                            Ok(())
-                        }
-                    } else if folder == "git" {
-                        match Repository::init(path) {
-                            Ok(_) => Ok(()),
-                            Err(e) => {
-                                if matches!(e.code(), git2::ErrorCode::Exists) {
-                                    log::warn!("Git repository already exists");
-                                    Ok(())
-                                } else {
-                                    Err(anyhow!(e))
+                    let result: anyhow::Result<()> = match folder {
+                        "git" => {
+                            match Repository::init(path) {
+                                Ok(_) => Ok(()),
+                                Err(e) => {
+                                    if matches!(e.code(), git2::ErrorCode::Exists) {
+                                        log::warn!("Git repository already exists");
+                                        Ok(())
+                                    } else {
+                                        Err(anyhow!(e))
+                                    }
                                 }
                             }
                         }
-                    } else if folder == "src2" {
-                        if let Some(path) = &project_path {
-                            let mut config = ProjectConfig::new(project_name.clone(), &path);
+                        "src2" => {
+                            let mut config = ProjectConfig::new(project_name.clone(), path);
                             let _ = config.write_to_all();
                             let mut global = PROJECT.write();
                             *global = config;
                             Ok(())
-                        } else {
-                            Err(anyhow!("Project path not found"))
                         }
-                    } else {
-                        if !full_path.exists() {
-                            fs::create_dir_all(&full_path)
-                                .map_err(|e| anyhow!(e))
-                                .map(|_| ())
-                        } else {
-                            log::warn!("{:?} already exists", full_path);
-                            Ok(())
+                        _ => {
+                            if !full_path.exists() {
+                                fs::create_dir_all(&full_path)
+                                    .map_err(|e| anyhow::anyhow!(e))
+                                    .map(|_| ())
+                            } else {
+                                log::warn!("{:?} already exists", full_path);
+                                Ok(())
+                            }
                         }
                     };
+
                     if let Err(e) = result {
-                        tx.send(ProjectProgress::Error(e.to_string())).ok();
+                        let _ = progress_tx.send(ProjectProgress::Error(e.to_string()));
                         errors.push(e);
                     }
                 }
-                tx.send(ProjectProgress::Step {
+
+                let _ = progress_tx.send(ProjectProgress::Step {
                     progress: 1.0,
-                    message: "Project creation complete!".to_string(),
-                })
-                .ok();
+                    message: "Finalizing project...".to_string(),
+                });
 
-                tx.send(ProjectProgress::Done).ok();
+                if errors.is_empty() {
+                    let _ = progress_tx.send(ProjectProgress::Done);
+                    Ok(()) // Success
+                } else {
+                    Err(anyhow!("Project creation failed with {} errors", errors.len()))
+                }
+            } else {
+                let _ = progress_tx.send(ProjectProgress::Error("Project path not set".to_string()));
+                Err(anyhow!("Project path not set"))
             }
         });
 
-        log::debug!("Starting project creation");
+        self.project_creation_handle = Some(handle);
+        queue.poll();
+        debug!("Starting project creation");
     }
 }
 
-#[async_trait::async_trait]
 impl Scene for MainMenu {
-    async fn load<'a>(&mut self, _graphics: &mut RenderContext<'a>) {
-        log::info!("Loaded menu scene");
+    fn load(&mut self, _graphics: &mut RenderContext) {
+        log::info!("Loaded main menu scene");
     }
 
-    async fn update<'a>(&mut self, _dt: f32, _graphics: &mut RenderContext<'a>) {}
+    fn update(&mut self, _dt: f32, _graphics: &mut RenderContext) {}
+
+    fn render(&mut self, graphics: &mut RenderContext) {
+        #[allow(clippy::collapsible_if)]
+        if let Some(handle) = self.project_creation_handle.as_ref() {
+            if let Some(result) = graphics.shared.future_queue.exchange_owned_as::<anyhow::Result<()>>(handle) {
+                self.project_creation_handle = None;
+
+                if result.is_ok() {
+                    log::info!("Project created successfully!");
+                    self.show_new_project = false;
+                    self.show_progress = false;
+                    self.scene_command = SceneCommand::SwitchScene("editor".to_string());
+                } else {
+                    log::error!("Project creation failed");
+                }
+            }
+        }
+        
+        #[allow(clippy::collapsible_if)]
+        if let Some(rx) = self.project_progress_rx.as_ref() {
+            if let Ok(true) = rx.has_changed() {
+                let progress = rx.borrow().clone();
+                match progress {
+                    ProjectProgress::Step { progress, message } => {
+                        self.progress = progress;
+                        self.progress_message = message;
+                    }
+                    ProjectProgress::Error(err) => {
+                        self.project_error.get_or_insert_with(Vec::new).push(err);
+                    }
+                    ProjectProgress::Done => {}
+                }
+            }
+        }
 
-    async fn render<'a>(&mut self, graphics: &mut RenderContext<'a>) {
         let screen_size: (f32, f32) = (
             graphics.shared.window.inner_size().width as f32 - 100.0,
             graphics.shared.window.inner_size().height as f32 - 100.0,
         );
         let egui_ctx = graphics.shared.get_egui_context();
         let mut local_open_project = false;
+        let mut local_select_project = false;
+
         egui::CentralPanel::default()
             .frame(Frame::new())
             .show(&egui_ctx, |ui| {
@@ -172,9 +215,10 @@ impl Scene for MainMenu {
                     ui.add_space(40.0);
 
                     let button_size = egui::vec2(300.0, 60.0);
+                    let is_busy = self.is_in_file_dialogue || self.project_creation_handle.is_some();
 
                     if ui
-                        .add_sized(button_size, egui::Button::new("New Project"))
+                        .add_enabled(!is_busy, egui::Button::new("New Project").min_size(button_size))
                         .clicked()
                     {
                         log::debug!("Creating new project");
@@ -183,7 +227,7 @@ impl Scene for MainMenu {
                     ui.add_space(20.0);
 
                     if ui
-                        .add_sized(button_size, egui::Button::new("Open Project"))
+                        .add_enabled(!is_busy, egui::Button::new("Open Project").min_size(button_size))
                         .clicked()
                     {
                         local_open_project = true;
@@ -191,7 +235,7 @@ impl Scene for MainMenu {
                     ui.add_space(20.0);
 
                     if ui
-                        .add_sized(button_size, egui::Button::new("Settings"))
+                        .add_enabled(!is_busy, egui::Button::new("Settings").min_size(button_size))
                         .clicked()
                     {
                         log::debug!("Settings (not implemented)");
@@ -199,54 +243,57 @@ impl Scene for MainMenu {
                     ui.add_space(20.0);
 
                     if ui
-                        .add_sized(button_size, egui::Button::new("Quit"))
+                        .add_enabled(!is_busy, egui::Button::new("Quit").min_size(button_size))
                         .clicked()
                     {
-                        self.scene_command = SceneCommand::Quit
+                        self.scene_command = SceneCommand::Quit;
                     }
                     ui.add_space(20.0);
                 });
             });
 
         if local_open_project {
-            log::debug!("Opening project");
+            debug!("Opening project dialog");
             self.is_in_file_dialogue = true;
-            if let Some(path) = rfd::AsyncFileDialog::new()
+
+            if let Some(path) = FileDialog::new()
                 .add_filter("Eucalyptus Configuration Files", &["eucp"])
                 .pick_file()
-                .await
             {
-                match ProjectConfig::read_from(&path.into()) {
+                match ProjectConfig::read_from(&path) {
                     Ok(config) => {
-                        log::info!("Loaded project!");
+                        log::info!("Loaded project: {:?}", path);
                         let mut global = PROJECT.write();
                         *global = config;
-                        // println!("Loaded config info: {:#?}", global);
-                        self.scene_command = SceneCommand::SwitchScene(String::from("editor"));
+                        self.scene_command = SceneCommand::SwitchScene("editor".to_string());
                     }
                     Err(e) => {
-                        if e.to_string().contains("missing field") {
-                            self.toast.add(egui_toast_fork::Toast {
+                        let error_msg = if e.to_string().contains("missing field") {
+                            "Project version is outdated. Please update your .eucp file."
+                        } else {
+                            &e.to_string()
+                        };
+
+                        self.toast.add(egui_toast_fork::Toast {
                             kind: egui_toast_fork::ToastKind::Error,
-                            text: format!("Your project version is not up to date with the current project version").into(),
+                            text: error_msg.to_string().into(),
                             options: ToastOptions::default()
-                                .duration_in_seconds(10.0)
+                                .duration_in_seconds(8.0)
                                 .show_progress(true),
                             ..Default::default()
                         });
-                            log::error!("Failed to load project: {}", e);
-                        }
+                        log::error!("Failed to load project: {}", e);
                     }
-                };
+                }
             } else {
-                log::warn!("File dialog returned \"None\"");
+                log::info!("User cancelled file dialog");
             }
+
             self.is_in_file_dialogue = false;
         }
 
         let mut show_new_project = self.show_new_project;
-        let mut local_select_project = false;
-        egui::Window::new("Create new project")
+        egui::Window::new("Create New Project")
             .open(&mut show_new_project)
             .resizable(true)
             .collapsible(false)
@@ -255,11 +302,10 @@ impl Scene for MainMenu {
                 ui.vertical(|ui| {
                     ui.heading("Project Name:");
                     ui.add_space(5.0);
-
                     ui.text_edit_singleline(&mut self.project_name);
                     ui.add_space(10.0);
 
-                    ui.heading("Project Location: ");
+                    ui.heading("Project Location:");
                     ui.add_space(5.0);
 
                     if let Some(ref path) = self.project_path {
@@ -267,71 +313,54 @@ impl Scene for MainMenu {
                         ui.add_space(5.0);
                     }
 
-                    ui.add_space(5.0);
                     if ui.button("Choose Location").clicked() {
                         local_select_project = true;
                     }
+                    ui.add_space(10.0);
 
                     let can_create = self.project_path.is_some() && !self.project_name.is_empty();
                     if ui
-                        .add_enabled(can_create, egui::Button::new("Create Project"))
+                        .add_enabled(can_create && !self.project_creation_handle.is_some(),
+                                     egui::Button::new("Create Project"))
                         .clicked()
                     {
                         log::info!("Creating new project at {:?}", self.project_path);
-                        self.start_project_creation();
-                        ui.ctx().request_repaint();
+                        self.start_project_creation(graphics.shared.future_queue.clone());
                     }
                 });
             });
         self.show_new_project = show_new_project;
 
         if local_select_project {
+            log::debug!("Opening folder picker");
             self.is_in_file_dialogue = true;
-            if let Some(path) = rfd::AsyncFileDialog::new()
-                .set_title("Save Project")
-                .set_file_name(&self.project_name)
+
+            let name = self.project_name.clone();
+            if let Some(path) = FileDialog::new()
+                .set_title("Select Project Folder")
+                .set_file_name(&name)
                 .pick_folder()
-                .await
             {
-                self.project_path = Some(path.into());
-                log::debug!("Project will be saved at: {:?}", self.project_path);
+                self.project_path = Some(path.clone());
+                log::debug!("Selected project location: {:?}", path);
             }
-            self.is_in_file_dialogue = false;
-        }
 
-        if let Some(rx) = self.progress_rx.as_mut() {
-            while let Ok(progress) = rx.try_recv() {
-                match progress {
-                    ProjectProgress::Step { progress, message } => {
-                        self.progress = progress;
-                        self.progress_message = message;
-                    }
-                    ProjectProgress::Error(err) => {
-                        self.project_error.get_or_insert_with(Vec::new).push(err);
-                    }
-                    ProjectProgress::Done if self.project_error.is_none() => {
-                        self.is_in_file_dialogue = false;
-                        self.show_new_project = false;
-                        self.show_progress = false;
-                        self.scene_command = SceneCommand::SwitchScene("editor".to_string());
-                    }
-                    ProjectProgress::Done => {}
-                }
-            }
+            self.is_in_file_dialogue = false;
         }
 
         if self.show_progress {
             egui::Window::new("Creating Project...")
-                .collapsible(true)
+                .collapsible(false)
                 .resizable(false)
-                .fixed_size([400.0, 120.0])
+                .fixed_size([400.0, 150.0])
                 .show(&egui_ctx, |ui| {
                     ui.label(&self.progress_message);
                     ui.add_space(10.0);
-
                     ui.add(egui::ProgressBar::new(self.progress).show_percentage());
+
                     if let Some(errors) = &self.project_error {
-                        ui.colored_label(egui::Color32::RED, "Errors:");
+                        ui.add_space(10.0);
+                        ui.colored_label(egui::Color32::RED, "Errors encountered:");
                         for err in errors {
                             ui.label(err);
                         }
@@ -339,11 +368,11 @@ impl Scene for MainMenu {
                 });
         }
 
-        self.toast.show(&graphics.shared.get_egui_context());
+        self.toast.show(&egui_ctx);
     }
 
     fn exit(&mut self, _event_loop: &ActiveEventLoop) {
-        log::info!("Exiting menu scene");
+        log::info!("Exiting main menu scene");
     }
 
     fn run_command(&mut self) -> SceneCommand {
@@ -353,10 +382,9 @@ impl Scene for MainMenu {
 
 impl Keyboard for MainMenu {
     fn key_down(&mut self, key: KeyCode, event_loop: &ActiveEventLoop) {
-        if key == KeyCode::Escape {
-            if !self.show_new_project && !self.is_in_file_dialogue {
-                event_loop.exit();
-            }
+        if key == KeyCode::Escape
+            && !self.show_new_project && !self.is_in_file_dialogue {
+            event_loop.exit();
         }
     }
 
@@ -365,9 +393,7 @@ impl Keyboard for MainMenu {
 
 impl Mouse for MainMenu {
     fn mouse_move(&mut self, _position: PhysicalPosition<f64>) {}
-
     fn mouse_down(&mut self, _button: MouseButton) {}
-
     fn mouse_up(&mut self, _button: MouseButton) {}
 }
 
@@ -395,4 +421,4 @@ impl Controller for MainMenu {
     fn on_disconnect(&mut self, id: gilrs::GamepadId) {
         debug!("Controller disconnected [{}]", id);
     }
-}
+}
\ No newline at end of file
diff --git a/eucalyptus-editor/src/signal.rs b/eucalyptus-editor/src/signal.rs
new file mode 100644
index 0000000..3e9ac1c
--- /dev/null
+++ b/eucalyptus-editor/src/signal.rs
@@ -0,0 +1,850 @@
+use std::sync::Arc;
+use egui::{Align2, Image};
+use dropbear_engine::camera::Camera;
+use dropbear_engine::entity::{AdoptedEntity, Transform};
+use dropbear_engine::graphics::SharedGraphicsContext;
+use dropbear_engine::lighting::{Light, LightComponent};
+use dropbear_engine::utils::{ResourceReference, ResourceReferenceType};
+use eucalyptus_core::states::{ModelProperties, ScriptComponent, Value};
+use eucalyptus_core::{info, scripting, success, success_without_console, warn, warn_without_console};
+use eucalyptus_core::camera::{CameraAction, CameraComponent, CameraFollowTarget, CameraType};
+use eucalyptus_core::scripting::ScriptAction;
+use eucalyptus_core::spawn::{push_pending_spawn, PendingSpawn};
+use crate::editor::{ComponentType, Editor, EditorState, EntityType, PendingSpawn2, Signal, UndoableAction};
+
+pub trait SignalController {
+    fn run_signal(&mut self, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<()>;
+}
+
+impl SignalController for Editor {
+    fn run_signal(&mut self, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<()> {
+        let mut local_insert_script = false;
+        let mut local_insert_camera = (false, String::new());
+        let mut local_signal: Option<Signal> = None;
+        let mut show = true;
+
+        match &self.signal {
+            Signal::None => {
+                Ok::<(), anyhow::Error>(())
+            }
+            Signal::Copy(_) => {Ok(())}
+            Signal::Paste(scene_entity) => {
+                let spawn = PendingSpawn {
+                    asset_path: scene_entity.model_path.clone(),
+                    asset_name: scene_entity.label.clone(),
+                    transform: scene_entity.transform,
+                    properties: scene_entity.properties.clone(),
+                    handle: None,
+                };
+                push_pending_spawn(spawn);
+                self.signal = Signal::Copy(scene_entity.clone());
+                Ok(())
+            },
+            Signal::Delete => {
+                if let Some(sel_e) = &self.selected_entity {
+                    let is_viewport_cam = if let Ok(mut q) = self.world
+                        .query_one::<&CameraComponent>(*sel_e)
+                    {
+                        if let Some(c) = q.get() {
+                            matches!(c.camera_type, CameraType::Debug)
+                        } else {
+                            false
+                        }
+                    } else {
+                        false
+                    };
+                    if is_viewport_cam {
+                        warn!("You can't delete the viewport camera");
+                        self.signal = Signal::None;
+                        Ok(())
+                    } else {
+                        match self.world.despawn(*sel_e) {
+                            Ok(_) => {
+                                info!("Decimated entity");
+                                self.signal = Signal::None;
+                                Ok(())
+                            }
+                            Err(e) => {
+                                self.signal = Signal::None;
+                                anyhow::bail!("Failed to delete entity: {}", e);
+                            }
+                        }
+                    }
+                } else {
+                    // no entity has been selected, so all good
+                    Ok(())
+                }
+            }
+            Signal::Undo => {
+                if let Some(action) = self.undo_stack.pop() {
+                    match action.undo(&mut self.world) {
+                        Ok(_) => {
+                            info!("Undid action");
+                        }
+                        Err(e) => {
+                            warn!("Failed to undo action: {}", e);
+                        }
+                    }
+                } else {
+                    warn_without_console!("Nothing to undo");
+                    log::debug!("No undoable actions in stack");
+                }
+                self.signal = Signal::None;
+                Ok(())
+            }
+            Signal::ScriptAction(action) => match action {
+                ScriptAction::AttachScript {
+                    script_path,
+                    script_name,
+                } => {
+                    if let Some(selected_entity) = self.selected_entity {
+                        match scripting::move_script_to_src(script_path) {
+                            Ok(moved_path) => {
+                                let new_script = ScriptComponent {
+                                    name: script_name.clone(),
+                                    path: moved_path.clone(),
+                                };
+
+                                let replaced = {
+                                    if let Ok(mut sc) = self.world.get::<&mut ScriptComponent>(selected_entity) {
+                                        sc.name = new_script.name.clone();
+                                        sc.path = new_script.path.clone();
+                                        true
+                                    } else {
+                                        false
+                                    }
+                                };
+
+                                if !replaced {
+                                    match scripting::attach_script_to_entity(
+                                        &mut self.world,
+                                        selected_entity,
+                                        new_script.clone(),
+                                    ) {
+                                        Ok(_) => {
+                                        }
+                                        Err(e) => {
+                                            self.signal = Signal::None;
+                                            anyhow::bail!("Failed to attach script to entity {:?}: {}",
+                                                selected_entity,
+                                                e);
+                                        }
+                                    }
+                                }
+
+                                {
+                                    if let Err(e) = scripting::convert_entity_to_group(
+                                        &mut self.world,
+                                        selected_entity,
+                                    ) {
+                                        log::warn!("convert_entity_to_group failed (non-fatal): {}", e);
+                                    }
+                                }
+
+                                success!(
+                                    "{} script '{}' at {} to entity {:?}",
+                                    if replaced { "Reattached" } else { "Attached" },
+                                    script_name,
+                                    moved_path.display(),
+                                    selected_entity
+                                );
+                            }
+                            Err(e) => {
+                                anyhow::bail!("Move failed: {}", e);
+                            }
+                        }
+                    } else {
+                        anyhow::bail!("AttachScript requested but no entity is selected");
+                    }
+
+                    self.signal = Signal::None;
+                    Ok(())
+                }
+                ScriptAction::CreateAndAttachScript {
+                    script_path,
+                    script_name,
+                } => {
+                    if let Some(selected_entity) = self.selected_entity {
+                        let new_script = ScriptComponent {
+                            name: script_name.clone(),
+                            path: script_path.clone(),
+                        };
+
+                        let replaced = {
+                            if let Ok(mut sc) = self.world.get::<&mut ScriptComponent>(selected_entity) {
+                                sc.name = new_script.name.clone();
+                                sc.path = new_script.path.clone();
+                                true
+                            } else {
+                                false
+                            }
+                        };
+
+                        if !replaced {
+                            match scripting::attach_script_to_entity(
+                                &mut self.world,
+                                selected_entity,
+                                new_script.clone(),
+                            ) {
+                                Ok(_) => {
+                                }
+                                Err(e) => {
+                                    self.signal = Signal::None;
+                                    anyhow::bail!("Failed to attach new script: {}", e);
+                                }
+                            }
+                        }
+
+                        {
+                            if let Err(e) = scripting::convert_entity_to_group(
+                                &mut self.world,
+                                selected_entity,
+                            ) {
+                                log::warn!("convert_entity_to_group failed (non-fatal): {}", e);
+                            }
+                        }
+
+                        success!(
+                            "{} new script '{}' at {} to entity {:?}",
+                            if replaced { "Replaced" } else { "Attached" },
+                            script_name,
+                            script_path.display(),
+                            selected_entity
+                        );
+                    } else {
+                        warn_without_console!("No selected entity to attach new script");
+                        log::warn!("CreateAndAttachScript requested but no entity is selected");
+                    }
+                    self.signal = Signal::None;
+                    Ok(())
+                }
+                ScriptAction::RemoveScript => {
+                    if let Some(selected_entity) = self.selected_entity {
+                        let mut success = false;
+                        let mut comp = ScriptComponent::default();
+                        {
+                            if let Ok(script) = self.world
+                                .remove_one::<ScriptComponent>(selected_entity)
+                            {
+                                success!("Removed script from entity {:?}", selected_entity);
+                                success = true;
+                                comp = script.clone();
+                            } else {
+                                warn!("No script component found on entity {:?}", selected_entity);
+                            }
+                        }
+
+                        if success {
+                            if let Err(e) = scripting::convert_entity_to_group(
+                                &mut self.world,
+                                selected_entity,
+                            ) {
+                                log::warn!("convert_entity_to_group failed (non-fatal): {}", e);
+                            }
+                            log::debug!("Pushing remove component to undo stack");
+                            UndoableAction::push_to_undo(
+                                &mut self.undo_stack,
+                                UndoableAction::RemoveComponent(
+                                    selected_entity,
+                                    Box::new(ComponentType::Script(comp)),
+                                ),
+                            );
+                        }
+                    } else {
+                        warn!("No entity selected to remove script from");
+                    }
+
+                    self.signal = Signal::None;
+                    Ok(())
+                }
+                ScriptAction::EditScript => {
+                    if let Some(selected_entity) = self.selected_entity {
+                        let script_opt = {
+                            if let Ok(mut q) = self.world.query_one::<&ScriptComponent>(selected_entity) {
+                                q.get().cloned()
+                            } else {
+                                None
+                            }
+                        };
+
+                        if let Some(script) = script_opt {
+                            match open::that(script.path.clone()) {
+                                Ok(()) => {
+                                    success!("Opened {}", script.name)
+                                }
+                                Err(e) => {
+                                    warn!("Error while opening {}: {}", script.name, e);
+                                }
+                            }
+                        } else {
+                            warn!("No script component found on entity {:?}", selected_entity);
+                        }
+                    } else {
+                        warn!("No entity selected to edit script");
+                    }
+                    self.signal = Signal::None;
+                    Ok(())
+                }
+            },
+            Signal::Play => {
+                let has_player_camera_target = self
+                    .world
+                    .query::<(&Camera, &CameraComponent, &CameraFollowTarget)>()
+                    .iter()
+                    .any(|(_, (_, comp, _))| matches!(comp.camera_type, CameraType::Player));
+
+                if has_player_camera_target {
+                    if let Err(e) = self.create_backup() {
+                        self.signal = Signal::None;
+                        anyhow::bail!("Failed to create play mode backup: {}", e);
+                    }
+
+                    self.editor_state = EditorState::Playing;
+
+                    self.switch_to_player_camera();
+
+                    let mut script_entities = Vec::new();
+                    {
+                        for (entity_id, script) in self.world
+                            .query::<&ScriptComponent>()
+                            .iter()
+                        {
+                            script_entities.push((entity_id, script.clone()));
+                        }
+                    }
+
+                    for (entity_id, script) in script_entities {
+                        log::debug!(
+                            "Initialising entity script [{}] from path: {}",
+                            script.name,
+                            script.path.display()
+                        );
+
+                        let bytes = match std::fs::read_to_string(&script.path) {
+                            Ok(val) => val,
+                            Err(e) => {
+                                self.signal = Signal::None;
+                                anyhow::bail!(
+                                    "Unable to read script {} to bytes because {}",
+                                    &script.path.display(),
+                                    e
+                                );
+                            }
+                        };
+
+                        match self.script_manager.load_script(
+                            &script
+                                .path
+                                .file_name()
+                                .unwrap()
+                                .to_string_lossy()
+                                .to_string(),
+                            bytes,
+                        ) {
+                            Ok(script_name) => {
+                                if let Err(e) = self.script_manager.init_entity_script(
+                                    entity_id,
+                                    &script_name,
+                                    &mut self.world,
+                                    &self.input_state,
+                                ) {
+                                    log::warn!(
+                                        "Failed to initialise script '{}' for entity {:?}: {}",
+                                        script.name,
+                                        entity_id,
+                                        e
+                                    );
+                                    self.signal = Signal::StopPlaying;
+                                } else {
+                                    success_without_console!(
+                                        "You are in play mode now! Press Escape to exit"
+                                    );
+                                    log::info!("You are in play mode now! Press Escape to exit");
+                                }
+                            }
+                            Err(e) => {
+                                // todo: proper error menu
+                                self.signal = Signal::StopPlaying;
+                                anyhow::bail!("Failed to load script '{}': {}", script.name, e);
+                            }
+                        }
+                    }
+                } else {
+                    anyhow::bail!("Unable to build: Player camera not attached to an entity");
+                }
+
+                self.signal = Signal::None;
+                Ok(())
+            }
+            Signal::StopPlaying => {
+                if let Err(e) = self.restore() {
+                    warn!("Failed to restore from play mode backup: {}", e);
+                    log::warn!("Failed to restore scene state: {}", e);
+                }
+
+                self.editor_state = EditorState::Editing;
+
+                self.switch_to_debug_camera();
+
+                // already kills itself
+                // for (entity_id, _) in Arc::get_mut(&mut self.world).unwrap().query::<&ScriptComponent>().iter() {
+                //     self.script_manager.remove_entity_script(entity_id);
+                // }
+
+                success!("Exited play mode");
+                log::info!("Back to the editor you go...");
+
+                self.signal = Signal::None;
+                Ok(())
+            }
+            Signal::CameraAction(action) => match action {
+                CameraAction::SetPlayerTarget { entity, offset } => {
+                    let player_camera = self
+                        .world
+                        .query::<(&Camera, &CameraComponent)>()
+                        .iter()
+                        .find_map(|(e, (_, comp))| {
+                            if matches!(comp.camera_type, CameraType::Player) {
+                                Some(e)
+                            } else {
+                                None
+                            }
+                        });
+
+                    if let Some(camera_entity) = player_camera {
+                        let mut follow_target = (false, CameraFollowTarget::default());
+                        if let Ok(mut query) = self.world
+                            .query_one::<&AdoptedEntity>(*entity)
+                            && let Some(adopted) = query.get() {
+                            follow_target = (
+                                true,
+                                CameraFollowTarget {
+                                    follow_target: adopted.model.label.to_string(),
+                                    offset: *offset,
+                                },
+                            );
+                        }
+
+                        {
+                            if follow_target.0 {
+                                let _ = self.world
+                                    .insert_one(camera_entity, follow_target);
+                                info!("Set player camera target to entity {:?}", entity);
+                            }
+                        }
+                    }
+                    self.signal = Signal::None;
+                    Ok(())
+                }
+                CameraAction::ClearPlayerTarget => {
+                    let player_camera = self
+                        .world
+                        .query::<(&Camera, &CameraComponent)>()
+                        .iter()
+                        .find_map(|(e, (_, comp))| {
+                            if matches!(comp.camera_type, CameraType::Player) {
+                                Some(e)
+                            } else {
+                                None
+                            }
+                        });
+
+                    if let Some(camera_entity) = player_camera {
+                        {
+                            let _ = self.world
+                                .remove_one::<CameraFollowTarget>(camera_entity);
+                        }
+                    }
+                    info!("Cleared player camera target");
+                    self.signal = Signal::None;
+                    Ok(())
+                }
+            },
+            Signal::AddComponent(entity, e_type) => {
+                match e_type {
+                    EntityType::Entity => {
+                        if let Ok(mut q) = self.world
+                            .query_one::<&AdoptedEntity>(*entity)
+                        {
+                            if let Some(e) = q.get() {
+                                let label = e.model.label.clone();
+                                egui::Window::new(format!("Add component for {}", label))
+                                    .title_bar(true)
+                                    .open(&mut show)
+                                    .scroll([false, true])
+                                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                                    .enabled(true)
+                                    .show(&graphics.get_egui_context(), |ui| {
+                                        if ui
+                                            .add_sized(
+                                                [ui.available_width(), 30.0],
+                                                egui::Button::new("Scripting"),
+                                            )
+                                            .clicked()
+                                        {
+                                            log::debug!(
+                                            "Adding scripting component to entity [{}]",
+                                            label
+                                        );
+                                            local_insert_script = true;
+                                            local_signal = Some(Signal::None);
+                                        }
+                                        if ui
+                                            .add_sized(
+                                                [ui.available_width(), 30.0],
+                                                egui::Button::new("Camera"),
+                                            )
+                                            .clicked()
+                                        {
+                                            log::debug!(
+                                            "Adding camera component to entity [{}]",
+                                            label
+                                        );
+
+                                            let has_camera = self.world
+                                                .query_one::<(&Camera, &CameraComponent)>(*entity)
+                                                .is_ok();
+
+                                            if has_camera {
+                                                warn!(
+                                                "Entity [{}] already has a camera component",
+                                                label
+                                            );
+                                            } else {
+                                                local_insert_camera = (true, label.clone());
+                                            }
+                                            local_signal = Some(Signal::None);
+                                        }
+                                    });
+
+                            }
+                        } else {
+                            log_once::warn_once!(
+                                "Failed to add component to entity: no entity component found"
+                            );
+                        }
+                        if local_insert_script {
+                            if let Err(e) = self.world
+                                .insert_one(entity.clone(), ScriptComponent::default())
+                            {
+                                warn!(
+                                    "Failed to add scripting component to entity: {}",
+                                    e
+                                );
+                            } else {
+                                success!("Added the scripting component");
+                            }
+                        }
+
+                        if local_insert_camera.0 {
+                            let camera = Camera::predetermined(
+                                graphics.clone(),
+                                Some(&format!("{} Camera", local_insert_camera.1)),
+                            );
+                            let component = CameraComponent::new();
+                            if let Err(e) = self.world
+                                .insert(*entity, (camera, component))
+                            {
+                                warn!(
+                                    "Failed to add camera component to entity: {}",
+                                    e
+                                );
+                            } else {
+                                success!("Added the camera component");
+                            }
+                        }
+                        Ok(())
+                    }
+                    EntityType::Light => {
+                        {
+                            if let Ok(mut q) = self.world
+                                .query_one::<&Light>(*entity)
+                            {
+                                if let Some(light) = q.get() {
+                                    let mut show = true;
+                                    egui::Window::new(format!("Add component for {}", light.label))
+                                        .scroll([false, true])
+                                        .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                                        .enabled(true)
+                                        .open(&mut show)
+                                        .title_bar(true)
+                                        .show(&graphics.get_egui_context(), |ui| {
+                                            if ui
+                                                .add_sized(
+                                                    [ui.available_width(), 30.0],
+                                                    egui::Button::new("Scripting"),
+                                                )
+                                                .clicked()
+                                            {
+                                                log::debug!(
+                                            "Adding scripting component to light [{}]",
+                                            light.label
+                                        );
+
+                                                success!(
+                                            "Added the scripting component to light [{}]",
+                                            light.label
+                                        );
+                                                self.signal = Signal::None;
+                                            }
+                                        });
+                                    if !show {
+                                        self.signal = Signal::None;
+                                    }
+                                }
+                                Ok(())
+                            } else {
+                                log_once::warn_once!(
+                                    "Failed to add component to light: no light component found"
+                                );
+                                Ok(())
+                            }
+                        }
+                    }
+                    EntityType::Camera => {
+                        {
+                            if let Ok(mut q) = self.world
+                                .query_one::<(&Camera, &CameraComponent)>(*entity)
+                            {
+                                if let Some((cam, _comp)) = q.get() {
+                                    let mut show = true;
+                                    egui::Window::new(format!("Add component for {}", cam.label))
+                                        .scroll([false, true])
+                                        .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                                        .enabled(true)
+                                        .open(&mut show)
+                                        .title_bar(true)
+                                        .show(&graphics.get_egui_context(), |ui| {
+                                            egui_extras::install_image_loaders(ui.ctx());
+                                            ui.add(Image::from_bytes(
+                                                "bytes://theres_nothing.jpg",
+                                                include_bytes!("../../resources/theres_nothing.jpg"),
+                                            ));
+                                            ui.label("Theres nothing...");
+                                            // scripting could be planned???
+                                            // if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Scripting")).clicked() {
+                                            //     log::debug!("Adding scripting component to camera [{}]", cam.label);
+
+                                            //     success!("Added the scripting component to camera [{}]", cam.label);
+                                            //     self.signal = Signal::None;
+                                            // }
+                                        });
+                                    if !show {
+                                        self.signal = Signal::None;
+                                    }
+                                }
+                                Ok(())
+                            } else {
+                                log_once::warn_once!(
+                                    "Failed to add component to light: no light component found"
+                                );
+                                Ok(())
+                            }
+                        }
+                    }
+                }
+            }
+            Signal::RemoveComponent(entity, c_type) =>
+                {match &**c_type {
+                    ComponentType::Script(_) => {
+                        match self.world
+                            .remove_one::<ScriptComponent>(*entity)
+                        {
+                            Ok(component) => {
+                                success!("Removed script component from entity {:?}", entity);
+                                UndoableAction::push_to_undo(
+                                    &mut self.undo_stack,
+                                    UndoableAction::RemoveComponent(
+                                        *entity,
+                                        Box::new(ComponentType::Script(component)),
+                                    ),
+                                );
+                            }
+                            Err(e) => {
+                                warn!("Failed to remove script component from entity: {}", e);
+                            }
+                        };
+                        self.signal = Signal::None;
+                        Ok(())
+                    }
+                    ComponentType::Camera(_, _, follow) => {
+                        if follow.is_some() {
+                            match self.world.remove::<(
+                                Camera,
+                                CameraComponent,
+                                CameraFollowTarget,
+                            )>(
+                                *entity
+                            ) {
+                                Ok(component) => {
+                                    success!("Removed camera component from entity {:?}", entity);
+                                    UndoableAction::push_to_undo(
+                                        &mut self.undo_stack,
+                                        UndoableAction::RemoveComponent(
+                                            *entity,
+                                            Box::new(ComponentType::Camera(
+                                                Box::new(component.0),
+                                                component.1,
+                                                Some(component.2),
+                                            )),
+                                        ),
+                                    );
+                                }
+                                Err(e) => {
+                                    warn!("Failed to remove camera component from entity: {}", e);
+                                }
+                            };
+                            Ok(())
+                        } else {
+                            match self.world
+                                .remove::<(Camera, CameraComponent)>(*entity)
+                            {
+                                Ok(component) => {
+                                    success!("Removed camera component from entity {:?}", entity);
+                                    UndoableAction::push_to_undo(
+                                        &mut self.undo_stack,
+                                        UndoableAction::RemoveComponent(
+                                            *entity,
+                                            Box::new(ComponentType::Camera(Box::new(component.0), component.1, None)),
+                                        ),
+                                    );
+                                }
+                                Err(e) => {
+                                    warn!("Failed to remove script component from entity: {}", e);
+                                }
+                            };
+                            Ok(())
+                        }
+                    }
+                }},
+            Signal::CreateEntity => {
+                let mut show = true;
+                egui::Window::new("Add Entity")
+                    .scroll([false, true])
+                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                    .enabled(true)
+                    .open(&mut show)
+                    .title_bar(true)
+                    .show(&graphics.get_egui_context(), |ui| {
+                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Model")).clicked() {
+                            log::debug!("Creating new model");
+                            warn!("Instead of using the `Add Entity` window, double click on the imported model in the asset \n\
+                            viewer to import a new model, then tweak the settings to how you wish after!");
+                            self.signal = Signal::None;
+                        }
+
+                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Light")).clicked() {
+                            log::debug!("Creating new lighting");
+                            self.signal = Signal::Spawn(PendingSpawn2::Light);
+                        }
+
+                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Plane")).clicked() {
+                            log::debug!("Creating new plane");
+                            self.signal = Signal::Spawn(PendingSpawn2::Plane);
+                        }
+
+                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Cube")).clicked() {
+                            log::debug!("Creating new cube");
+                            self.signal = Signal::Spawn(PendingSpawn2::Cube);
+                        }
+
+                        if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Camera")).clicked() {
+                            log::debug!("Creating new cube");
+                            self.signal = Signal::Spawn(PendingSpawn2::Camera);
+                        }
+                    });
+                if !show {
+                    self.signal = Signal::None;
+                }
+                Ok(())
+            }
+            Signal::LogEntities => {
+                log::debug!("====================");
+                let mut counter = 0;
+                for entity in self.world.iter() {
+                    if let Some(entity) = entity.get::<&AdoptedEntity>() {
+                        log::info!("Model: {:?}", entity.model.label);
+                        log::info!("  |-> Using model: {:?}", entity.model.id);
+                    }
+
+                    if let Some(entity) = entity.get::<&Light>() {
+                        log::info!("Light: {:?}", entity.cube_model.label);
+                        log::info!("  |-> Using model: {:?}", entity.cube_model.id);
+                    }
+
+                    if entity.get::<&Camera>().is_some() {
+                        log::info!("Camera");
+                    }
+                    counter += 1;
+                }
+                log::debug!("====================");
+                info!("Total entity count: {}", counter);
+                self.signal = Signal::None;
+                Ok(())
+            }
+            Signal::Spawn(entity_type) => {
+                match entity_type {
+                    crate::editor::PendingSpawn2::Light => {
+                        let light = Light::new(graphics.clone(), LightComponent::default(), Transform::new(), Some("Default Light"));
+                        let handle = graphics.future_queue.push(light);
+                        self.alt_pending_spawn_queue.push(handle);
+                        success!("Pushed light to queue");
+                    }
+                    crate::editor::PendingSpawn2::Plane => {
+                        let transform = Transform::new();
+                        let mut props = ModelProperties::new();
+                        props
+                            .custom_properties
+                            .insert("width".to_string(), Value::Float(500.0));
+                        props
+                            .custom_properties
+                            .insert("height".to_string(), Value::Float(200.0));
+                        props
+                            .custom_properties
+                            .insert("tiles_x".to_string(), Value::Int(500));
+                        props
+                            .custom_properties
+                            .insert("tiles_z".to_string(), Value::Int(200));
+                        push_pending_spawn(PendingSpawn {
+                            asset_path: ResourceReference::from_reference(ResourceReferenceType::Plane),
+                            asset_name: "DefaultPlane".to_string(),
+                            transform,
+                            properties: props,
+                            handle: None,
+                        });
+                        success!("Pushed plane to queue");
+                    }
+                    PendingSpawn2::Cube => {
+                        let pending = PendingSpawn {
+                            asset_path: ResourceReference::from_bytes(include_bytes!("../../resources/cube.glb")),
+                            asset_name: "Default Cube".to_string(),
+                            transform: Default::default(),
+                            properties: Default::default(),
+                            handle: None,
+                        };
+                        push_pending_spawn(pending);
+                        success!("Pushed cube to queue");
+                    }
+                    PendingSpawn2::Camera => {
+                        let camera = Camera::predetermined(graphics.clone(), None);
+                        let component = CameraComponent::new();
+                        {
+                            self.world
+                                .spawn((camera, component));
+                        }
+                        success!("Pushed camera to queue");
+                    }
+                }
+                self.signal = Signal::None;
+                return Ok(());
+            }
+        }?;
+        if !show {
+            self.signal = Signal::None;
+        }
+        if let Some(signal) = local_signal {
+            self.signal = signal;
+        }
+        Ok(())
+    }
+}
\ No newline at end of file
diff --git a/eucalyptus-editor/src/spawn.rs b/eucalyptus-editor/src/spawn.rs
new file mode 100644
index 0000000..0b297b4
--- /dev/null
+++ b/eucalyptus-editor/src/spawn.rs
@@ -0,0 +1,131 @@
+use std::sync::Arc;
+use dropbear_engine::entity::AdoptedEntity;
+use dropbear_engine::future::FutureQueue;
+use dropbear_engine::graphics::SharedGraphicsContext;
+use dropbear_engine::model::Model;
+use dropbear_engine::procedural::plane::PlaneBuilder;
+use dropbear_engine::utils::ResourceReferenceType;
+pub(crate) use eucalyptus_core::spawn::{PendingSpawnController, PENDING_SPAWNS};
+use eucalyptus_core::states::{Value, PROJECT};
+use eucalyptus_core::utils::PROTO_TEXTURE;
+use crate::editor::Editor;
+
+impl PendingSpawnController for Editor {
+    fn check_up(&mut self, graphics: Arc<SharedGraphicsContext>, queue: Arc<FutureQueue>) -> anyhow::Result<()> {
+        queue.poll();
+        let mut spawn_list = PENDING_SPAWNS.lock();
+
+        let mut completed = Vec::new();
+
+        for (i, spawn) in spawn_list.iter_mut().enumerate() {
+            log_once::debug_once!("Caught pending spawn! Info: {} of type {}", spawn.asset_name, spawn.asset_path);
+            if spawn.handle.is_none() {
+                log_once::debug_once!("Pending spawn does NOT have a handle, creating new one now");
+                let graphics_clone = graphics.clone();
+                let asset_name = spawn.asset_name.clone();
+                let asset_path = spawn.asset_path.ref_type.clone();
+                let properties = spawn.properties.clone();
+
+                let func = async move {
+                    match asset_path {
+                        ResourceReferenceType::None => {
+                            Err(anyhow::anyhow!("No asset path available"))
+                        }
+                        ResourceReferenceType::File(file) => {
+                            let path = {
+                                let _guard = PROJECT.read();
+                                _guard.project_path.clone()
+                            };
+                            let resource = path.join("resources").join(file);
+                            AdoptedEntity::new(graphics_clone, resource, Some(&asset_name)).await
+                        }
+                        ResourceReferenceType::Bytes(bytes) => {
+                            let model = Model::load_from_memory(graphics_clone.clone(), &bytes, Some(&asset_name)).await?;
+                            Ok(AdoptedEntity::adopt(graphics_clone, model).await)
+                        }
+                        ResourceReferenceType::Plane => {
+                            let get_float = |key: &str| -> anyhow::Result<f32> {
+                                let val = properties.custom_properties
+                                    .get(key)
+                                    .ok_or_else(|| anyhow::anyhow!("Entity has no {} property", key))?;
+                                match val {
+                                    Value::Float(f) => Ok(*f as f32),
+                                    _ => Err(anyhow::anyhow!("{} is not a float", key)),
+                                }
+                            };
+
+                            let get_int = |key: &str| -> anyhow::Result<u32> {
+                                let val = properties.custom_properties
+                                    .get(key)
+                                    .ok_or_else(|| anyhow::anyhow!("Entity has no {} property", key))?;
+                                match val {
+                                    Value::Int(i) => Ok(*i as u32),
+                                    _ => Err(anyhow::anyhow!("{} is not an int", key)),
+                                }
+                            };
+
+                            let width = get_float("width")?;
+                            let height = get_float("height")?;
+                            let tiles_x = get_int("tiles_x")?;
+                            let tiles_z = get_int("tiles_z")?;
+
+                            PlaneBuilder::new()
+                                .with_size(width, height)
+                                .with_tiles(tiles_x, tiles_z)
+                                .build(graphics_clone, PROTO_TEXTURE, Some(&asset_name))
+                                .await
+                        }
+                    }
+                };
+
+                let handle = queue.push(Box::pin(func));
+                spawn.handle = Some(handle);
+            } else {
+                log_once::debug_once!("Spawn does have handle, using that one");
+            }
+
+            if let Some(handle) = &spawn.handle {
+                log_once::debug_once!("Handle located");
+                if let Some(result) = queue.exchange_owned(handle) {
+                    log_once::debug_once!("Loading done, located result");
+                    if let Ok(r) = result
+                        .downcast::<anyhow::Result<AdoptedEntity>>() {
+                        log_once::debug_once!("Result has been successfully downcasted");
+                        match Arc::try_unwrap(r) {
+                            Ok(entity) => {
+                                match entity {
+                                    Ok(entity) => {
+                                        log::debug!("Entity loaded");
+                                        self.world.spawn((entity, spawn.transform, spawn.properties.clone()));
+                                        completed.push(i);
+                                    }
+                                    Err(e) => {
+                                        log_once::error_once!("Unable to load model: {}", e);
+                                        completed.push(i);
+                                    }
+                                }
+
+                            }
+                            Err(_) => return {
+                                log_once::warn_once!("Cannot unwrap Arc result");
+                                completed.push(i);
+                                Ok(())
+                            },
+                        }
+                    }
+                } else {
+                    log_once::debug_once!("Handle exchanging failed, probably not ready yet");
+                }
+            } else {
+                log_once::debug_once!("Spawn has no handle");
+            }
+        }
+
+        for &i in completed.iter().rev() {
+            log_once::debug_once!("Removing item {} from pending spawn list", i);
+            spawn_list.remove(i);
+        }
+
+        Ok(())
+    }
+}
\ No newline at end of file
diff --git a/eucalyptus-editor/src/utils.rs b/eucalyptus-editor/src/utils.rs
index 3c0598d..d62949d 100644
--- a/eucalyptus-editor/src/utils.rs
+++ b/eucalyptus-editor/src/utils.rs
@@ -45,15 +45,14 @@ pub fn show_new_project_window<F>(
                 }
 
                 ui.add_space(5.0);
-                if ui.button("Choose Location").clicked() {
-                    if let Some(path) = rfd::FileDialog::new()
+                if ui.button("Choose Location").clicked()
+                    && let Some(path) = rfd::FileDialog::new()
                         .set_title("Save Project")
                         .set_file_name(project_name.clone())
                         .pick_folder()
                     {
                         *project_path = Some(path);
                     }
-                }
 
                 let can_create = project_path.is_some() && !project_name.is_empty();
                 if ui
@@ -150,7 +149,7 @@ pub fn start_project_creation(
                     }
                 } else if folder == "src2" {
                     if let Some(path) = &project_path {
-                        let mut config = ProjectConfig::new(project_name.clone(), &path);
+                        let mut config = ProjectConfig::new(project_name.clone(), path);
                         let _ = config.write_to_all();
                         let mut global = PROJECT.write();
                         *global = config;
@@ -158,14 +157,12 @@ pub fn start_project_creation(
                     } else {
                         Err(anyhow!("Project path not found"))
                     }
+                } else if !full_path.exists() {
+                    fs::create_dir_all(&full_path)
+                        .map_err(|e| anyhow!(e))
+                        .map(|_| ())
                 } else {
-                    if !full_path.exists() {
-                        fs::create_dir_all(&full_path)
-                            .map_err(|e| anyhow!(e))
-                            .map(|_| ())
-                    } else {
-                        Ok(())
-                    }
+                    Ok(())
                 };
                 if let Err(e) = result {
                     tx.send(ProjectProgress::Error(e.to_string())).ok();
diff --git a/src/dropbear.gleam b/src/dropbear.gleam
index 555e244..e0f82f6 100644
--- a/src/dropbear.gleam
+++ b/src/dropbear.gleam
@@ -1,3 +1,60 @@
-/// Queries the attached entity. Returns a serialized string to be decoded. 
-@external(javascript, "dropbear", "queryAttachedEntity")
-fn raw_query_attached_entity() -> String
\ No newline at end of file
+//// The bridge used for connecting between the dropbear-engine and the
+//// gleam WASM interface.
+////
+//// This can be ran on it's own, but it is pretty useless without attaching to an entity.
+////
+//// # Compile Pipeline
+//// In the rust interface, it compiles Gleam using a Gleam -> JavaScript -> WASM (using javy). Despite using javy
+//// creating large amounts of overhead, it is best choice for compiling JavaScript.
+////
+//// # Targets
+//// Currently, Erlang targets do not do anything (unless you can compile to WASM, which I'm pretty sure you can't.
+//// There is also no library available for a Gleam <-> Rust connection, nor is there a Erlang <-> Rust **practical**
+//// connection. Also, using Erlang for a game engine is extremely impractical and stupid (and a pain to setup).
+////
+//// My other thoughts were to use OCaml, but OCaml has a high learning curve (as if Gleam doesn't already), and is
+//// hard to setup up, including dealing with FFI.
+////
+//// Gleam just seemed like the best language: niche, rising to popularity, can be compiled and integrates with Rust,
+//// and most importantly: Type safety.
+
+import gleam/dict
+import math
+import gleam/option
+import entity
+
+/// The id returned during a query, which allows you to query for other features
+/// 
+/// A very primitive type. 
+pub type QueryId {
+  QueryId(id: Int)
+}
+
+/// Queries the current entity the script is attached to.
+///
+/// Returns None is the script is not attached to anything (i.e. a library), or Some if it is attached,
+/// along with the entity information as shown in `dropbear/entity.Entity`.
+pub fn query_current_entity() -> option.Option(entity.Entity) {
+  option.Some(entity.Entity(0, transform: math.new_transform(), properties: dict.new(), dirty: False, before_dirty_entity: entity.BeforeSyncedEntity(id: 0, transform: math.new_transform(), properties: dict.new())))
+
+}
+
+/// A command that syncs/pushes the data back to the game engine interface.
+///
+/// It is typically automatically triggered at the end of a function (such as at the end of a move function), but can
+/// be triggered manually by running the command.
+///
+/// The sync command takes an input of entity (so perfect for chaining), and then returning an entity. It also updates
+/// the BeforeSyncedEntity to its current iteration.
+pub fn sync(entity: entity.Entity) -> entity.Entity {
+  case entity.dirty {
+    True -> {
+      // mock sync/push
+      entity.Entity(..entity, before_dirty_entity: entity.new_before_synced_entity_from_existing_entity(entity))
+    }
+    False -> {
+      // just return back the entity
+      entity
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/entity.gleam b/src/entity.gleam
new file mode 100644
index 0000000..31fa752
--- /dev/null
+++ b/src/entity.gleam
@@ -0,0 +1,65 @@
+//// A module for storing the properties of entities, as well as the manipulation of entities.
+
+import gleam/dict
+import types
+import math
+
+/// A standard type for an entity.
+pub type Entity {
+    Entity(
+        /// The id/reference
+        id: Int,
+        /// The position, rotation and scale of the entity
+        transform: math.Transform,
+        /// The properties of the entity, stored in a gleam dictionary as a String key and
+        /// Value type.
+        properties: dict.Dict(String, types.Value),
+        /// An internal value that checks if the entity is "dirty" and needs to be synced up.
+        ///
+        /// It can be manually synced up using the `dropbear.sync()` command, but in the case
+        /// that it is not used, this flag pushes the changes at the end of the update function.
+        dirty: Bool,
+        before_dirty_entity: BeforeSyncedEntity,
+    )
+}
+
+/// Creates a "dummy"/placeholder value for an Entity.
+///
+/// It's ID is always set to -1 so it cannot be used in any queries.
+pub fn dummy() -> Entity {
+    Entity(id: -1, transform: math.new_transform(), properties: dict.new(), dirty: False, before_dirty_entity: dummy_before())
+}
+
+/// A type used to checked the latest synced change. This is mainly internal, however you can use it
+/// to check which values are dirty or not.
+pub type BeforeSyncedEntity {
+    BeforeSyncedEntity(
+        /// The id/reference
+        id: Int,
+        /// The position, rotation and scale of the entity
+        transform: math.Transform,
+        /// The properties of the entity, stored in a gleam dictionary as a String key and
+        /// Value type.
+        properties: dict.Dict(String, types.Value),
+    )
+}
+
+/// Creates a new dummy value for a BeforeSyncedEntity.
+///
+/// It's ID is always set to -1 so it cannot be used in any queries.
+pub fn dummy_before() -> BeforeSyncedEntity {
+    BeforeSyncedEntity(id: -1, transform: math.new_transform(), properties: dict.new())
+}
+
+/// A hella long name, creates a new BeforeSyncedEntity from an existing Entity.
+///
+/// It mainly exists as an internal helper, thats all...
+pub fn new_before_synced_entity_from_existing_entity(entity: Entity) -> BeforeSyncedEntity {
+    BeforeSyncedEntity(id: entity.id, transform: entity.transform, properties: entity.properties)
+}
+
+/// Sets the position of the entity
+pub fn set_position(entity: Entity, position: math.Vector3(Float)) -> Entity {
+    let transform = math.Transform(..entity.transform, position: position)
+    Entity(..entity, transform:transform, dirty: True)
+}
\ No newline at end of file
diff --git a/src/example.gleam b/src/example.gleam
new file mode 100644
index 0000000..29253a0
--- /dev/null
+++ b/src/example.gleam
@@ -0,0 +1,44 @@
+//// A dummy file, do not use. I mean, use it if you want, its public for a reason...
+
+import gleam/io
+import gleam/string
+import gleam/option.{Some}
+import math
+import entity
+import dropbear
+
+pub fn main() {
+  load()
+  update(0.016)
+}
+
+pub fn load() -> Nil {
+  let _ = case dropbear.query_current_entity() {
+    Some(entity) -> {
+        entity.set_position(entity, math.Vector3(1.0, 1.0, 1.0))
+        |> dropbear.sync()
+    }
+    option.None -> {
+      entity.dummy()
+    }
+  }
+
+  io.println("Loaded!")
+}
+
+pub fn update(dt: Float) -> Nil {
+  io.println("Updating...")
+  let _ = case dropbear.query_current_entity() {
+    Some(entity) -> {
+      io.println("Successfully queried entity!")
+      entity.set_position(entity, math.Vector3(1.0, 1.0, 1.0))
+      |> dropbear.sync()
+    }
+    option.None -> {
+      io.println("Could not query entity, creating a dummy entity")
+      entity.dummy()
+    }
+  }
+  io.println("Deltatime is " <> string.inspect(dt))
+  update(dt)
+}
\ No newline at end of file
diff --git a/src/input.gleam b/src/input.gleam
index e69de29..187af64 100644
--- a/src/input.gleam
+++ b/src/input.gleam
@@ -0,0 +1,2 @@
+//// A module for input management and input detection from different IO devices
+//// such as keyboards, mice, and game controllers (for now).
\ No newline at end of file
diff --git a/src/math.gleam b/src/math.gleam
index 5408a5e..6f95de0 100644
--- a/src/math.gleam
+++ b/src/math.gleam
@@ -1,57 +1,59 @@
-/// The generic type of an entity, containing a position, rotation and scale. 
+//// A module for the basic types of math that the gleam standard library didn't include.
+
+/// The generic type of an entity, containing a position, rotation and scale.
 pub type Transform {
-    Transform (
-        position: Vector3(Float),
-        rotation: Quaternion(Float),
-        scale: Vector3(Float),
-    )
+  Transform (
+  position: Vector3(Float),
+  rotation: Quaternion(Float),
+  scale: Vector3(Float),
+  )
 }
 
 /// Creates a new transform
 pub fn new_transform() -> Transform {
-    Transform(
-        position: zero_vector3f(),
-        rotation: identity_quatf(),
-        scale: zero_vector3f(),
-    )
+  Transform(
+    position: zero_vector3f(),
+    rotation: identity_quatf(),
+    scale: zero_vector3f(),
+  )
 }
 
-/// A type used to show 3 instances of a value. 
+/// A type used to show 3 instances of a value.
 pub type Vector3(a) {
-    Vector3(
-        /// X value
-        x: a,
-        /// Y value
-        y: a,
-        /// Z value
-        z: a,
-    )
+  Vector3(
+  /// X value
+  x: a,
+  /// Y value
+  y: a,
+  /// Z value
+  z: a,
+  )
 }
 
-/// Creates a new Vector3(Float) of all 0.0. 
+/// Creates a new Vector3(Float) of all 0.0.
 pub fn zero_vector3f() -> Vector3(Float) {
-    Vector3(
-        x: 0.0,
-        y: 0.0,
-        z: 0.0,
-    )
+  Vector3(
+  x: 0.0,
+  y: 0.0,
+  z: 0.0,
+  )
 }
 
 pub type Quaternion(a) {
-    Quaternion(
-        w: a,
-        x: a,
-        y: a,
-        z: a,
-    )
+  Quaternion(
+  w: a,
+  x: a,
+  y: a,
+  z: a,
+  )
 }
 
-/// Creates a new quaternion with 1.0 as the scale and 0.0 for the x, y and z. 
+/// Creates a new quaternion with 1.0 as the scale and 0.0 for the x, y and z.
 pub fn identity_quatf() -> Quaternion(Float) {
-    Quaternion(
-        w: 1.0,
-        x: 0.0,
-        y: 0.0,
-        z: 0.0,
-    )
+  Quaternion(
+  w: 1.0,
+  x: 0.0,
+  y: 0.0,
+  z: 0.0,
+  )
 }
\ No newline at end of file
diff --git a/src/types.gleam b/src/types.gleam
new file mode 100644
index 0000000..3123bde
--- /dev/null
+++ b/src/types.gleam
@@ -0,0 +1,13 @@
+//// Different types and values available to be used.
+
+/// A generic value. It is used in the entity properties.
+pub type Value {
+    /// Integer
+    Int(Int)
+    /// Float
+    Float(Float)
+    /// String
+    String(String)
+    /// Boolean
+    Bool(Bool)
+}
\ No newline at end of file