From 8d2ba28700cff7ae481c076e6767ce86888ae599 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Wed, 22 Jan 2025 04:18:23 -0800
Subject: [PATCH] move engine components into modules

---
 Cargo.lock                                    | 55 +++++++++++++++++--
 Cargo.toml                                    |  4 ++
 engine/graphics/Cargo.toml                    | 14 +++++
 engine/graphics/LICENSE                       |  8 +++
 .../graphics}/src/graphics.rs                 | 28 ++++++----
 engine/graphics/src/lib.rs                    |  2 +
 .../graphics/src/model.rs                     |  0
 engine/physics/Cargo.toml                     | 10 ++++
 engine/physics/LICENSE                        |  8 +++
 {strafe-client => engine/physics}/src/body.rs |  2 +-
 .../physics}/src/face_crawler.rs              |  2 +-
 engine/physics/src/lib.rs                     |  6 ++
 .../physics/src/model.rs                      |  0
 .../physics}/src/physics.rs                   |  2 +-
 .../physics}/src/push_solve.rs                |  0
 engine/session/Cargo.toml                     | 12 ++++
 engine/session/LICENSE                        |  8 +++
 engine/session/src/lib.rs                     |  2 +
 .../session}/src/mouse_interpolator.rs        |  0
 .../session}/src/session.rs                   | 16 +++---
 engine/settings/Cargo.toml                    |  9 +++
 engine/settings/LICENSE                       |  8 +++
 engine/settings/src/lib.rs                    |  1 +
 .../settings}/src/settings.rs                 |  0
 strafe-client/Cargo.toml                      | 10 ++--
 strafe-client/src/graphics_worker.rs          | 12 ++--
 strafe-client/src/main.rs                     | 10 ----
 strafe-client/src/physics_worker.rs           | 11 ++--
 strafe-client/src/setup.rs                    |  5 +-
 strafe-client/src/window.rs                   |  9 +--
 strafe-client/src/worker.rs                   |  2 +-
 31 files changed, 194 insertions(+), 62 deletions(-)
 create mode 100644 engine/graphics/Cargo.toml
 create mode 100644 engine/graphics/LICENSE
 rename {strafe-client => engine/graphics}/src/graphics.rs (96%)
 create mode 100644 engine/graphics/src/lib.rs
 rename strafe-client/src/model_graphics.rs => engine/graphics/src/model.rs (100%)
 create mode 100644 engine/physics/Cargo.toml
 create mode 100644 engine/physics/LICENSE
 rename {strafe-client => engine/physics}/src/body.rs (98%)
 rename {strafe-client => engine/physics}/src/face_crawler.rs (98%)
 create mode 100644 engine/physics/src/lib.rs
 rename strafe-client/src/model_physics.rs => engine/physics/src/model.rs (100%)
 rename {strafe-client => engine/physics}/src/physics.rs (99%)
 rename {strafe-client => engine/physics}/src/push_solve.rs (100%)
 create mode 100644 engine/session/Cargo.toml
 create mode 100644 engine/session/LICENSE
 create mode 100644 engine/session/src/lib.rs
 rename {strafe-client => engine/session}/src/mouse_interpolator.rs (100%)
 rename {strafe-client => engine/session}/src/session.rs (97%)
 create mode 100644 engine/settings/Cargo.toml
 create mode 100644 engine/settings/LICENSE
 create mode 100644 engine/settings/src/lib.rs
 rename {strafe-client => engine/settings}/src/settings.rs (100%)

diff --git a/Cargo.lock b/Cargo.lock
index 9d0ac9d8..396e9eb9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2253,19 +2253,17 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 name = "strafe-client"
 version = "0.11.0"
 dependencies = [
- "arrayvec",
- "bytemuck",
- "configparser",
- "ddsfile",
  "glam",
- "id",
  "parking_lot",
  "pollster",
- "replace_with",
  "strafesnet_bsp_loader",
  "strafesnet_common",
  "strafesnet_deferred_loader",
+ "strafesnet_graphics",
+ "strafesnet_physics",
  "strafesnet_rbx_loader",
+ "strafesnet_session",
+ "strafesnet_settings",
  "strafesnet_snf",
  "wgpu",
  "winit",
@@ -2303,6 +2301,30 @@ dependencies = [
  "vbsp",
 ]
 
+[[package]]
+name = "strafesnet_graphics"
+version = "0.1.0"
+dependencies = [
+ "bytemuck",
+ "ddsfile",
+ "glam",
+ "id",
+ "strafesnet_common",
+ "strafesnet_session",
+ "strafesnet_settings",
+ "wgpu",
+]
+
+[[package]]
+name = "strafesnet_physics"
+version = "0.1.0"
+dependencies = [
+ "arrayvec",
+ "glam",
+ "id",
+ "strafesnet_common",
+]
+
 [[package]]
 name = "strafesnet_rbx_loader"
 version = "0.5.2"
@@ -2319,6 +2341,27 @@ dependencies = [
  "strafesnet_common",
 ]
 
+[[package]]
+name = "strafesnet_session"
+version = "0.1.0"
+dependencies = [
+ "glam",
+ "replace_with",
+ "strafesnet_common",
+ "strafesnet_physics",
+ "strafesnet_settings",
+ "strafesnet_snf",
+]
+
+[[package]]
+name = "strafesnet_settings"
+version = "0.1.0"
+dependencies = [
+ "configparser",
+ "glam",
+ "strafesnet_common",
+]
+
 [[package]]
 name = "strafesnet_snf"
 version = "0.2.0"
diff --git a/Cargo.toml b/Cargo.toml
index 02451d0f..cca86f0f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,9 @@
 [workspace]
 members = [
+	"engine/graphics",
+	"engine/physics",
+	"engine/session",
+	"engine/settings",
 	"lib/bsp_loader",
 	"lib/common",
 	"lib/deferred_loader",
diff --git a/engine/graphics/Cargo.toml b/engine/graphics/Cargo.toml
new file mode 100644
index 00000000..a62689ad
--- /dev/null
+++ b/engine/graphics/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "strafesnet_graphics"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+bytemuck = { version = "1.13.1", features = ["derive"] }
+ddsfile = "0.5.1"
+glam = "0.29.0"
+id = { version = "0.1.0", registry = "strafesnet" }
+strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
+strafesnet_session = { path = "../session", registry = "strafesnet" }
+strafesnet_settings = { path = "../settings", registry = "strafesnet" }
+wgpu = "24.0.0"
diff --git a/engine/graphics/LICENSE b/engine/graphics/LICENSE
new file mode 100644
index 00000000..f6ff6bc0
--- /dev/null
+++ b/engine/graphics/LICENSE
@@ -0,0 +1,8 @@
+/*******************************************************
+* Copyright (C) 2023-2024 Rhys Lloyd <krakow20@gmail.com>
+*
+* This file is part of the StrafesNET bhop/surf client.
+*
+* StrafesNET can not be copied and/or distributed
+* without the express permission of Rhys Lloyd
+*******************************************************/
\ No newline at end of file
diff --git a/strafe-client/src/graphics.rs b/engine/graphics/src/graphics.rs
similarity index 96%
rename from strafe-client/src/graphics.rs
rename to engine/graphics/src/graphics.rs
index 8002da74..a7340df5 100644
--- a/strafe-client/src/graphics.rs
+++ b/engine/graphics/src/graphics.rs
@@ -1,9 +1,15 @@
 use std::borrow::Cow;
 use std::collections::{HashSet,HashMap};
 use strafesnet_common::map;
+use strafesnet_settings::settings;
+use strafesnet_session::session;
 use strafesnet_common::model::{self, ColorId, NormalId, PolygonIter, PositionId, RenderConfigId, TextureCoordinateId, VertexId};
 use wgpu::{util::DeviceExt,AstcBlock,AstcChannel};
-use crate::model_graphics::{self,IndexedGraphicsMeshOwnedRenderConfig,IndexedGraphicsMeshOwnedRenderConfigId,GraphicsMeshOwnedRenderConfig,GraphicsModelColor4,GraphicsModelOwned,GraphicsVertex};
+use crate::model::{self as model_graphics,IndexedGraphicsMeshOwnedRenderConfig,IndexedGraphicsMeshOwnedRenderConfigId,GraphicsMeshOwnedRenderConfig,GraphicsModelColor4,GraphicsModelOwned,GraphicsVertex};
+
+pub fn required_limits()->wgpu::Limits{
+	wgpu::Limits::default()
+}
 
 struct Indices{
 	count:u32,
@@ -136,7 +142,7 @@ impl GraphicsState{
 	pub fn clear(&mut self){
 		self.models.clear();
 	}
-	pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){
+	pub fn load_user_settings(&mut self,user_settings:&settings::UserSettings){
 		self.camera.fov=user_settings.calculate_fov(1.0,&self.camera.screen_size).as_vec2();
 	}
 	pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::CompleteMap){
@@ -448,7 +454,7 @@ impl GraphicsState{
 		//.into_iter() the modeldata vec so entities can be /moved/ to models.entities
 		let mut model_count=0;
 		let mut instance_count=0;
-		let uniform_buffer_binding_size=crate::setup::required_limits().max_uniform_buffer_binding_size as usize;
+		let uniform_buffer_binding_size=required_limits().max_uniform_buffer_binding_size as usize;
 		let chunk_size=uniform_buffer_binding_size/MODEL_BUFFER_SIZE_BYTES;
 		self.models.reserve(models.len());
 		for model in models.into_iter(){
@@ -608,7 +614,7 @@ impl GraphicsState{
 		// Create the render pipeline
 		let shader=device.create_shader_module(wgpu::ShaderModuleDescriptor{
 			label:None,
-			source:wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))),
+			source:wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("../../../strafe-client/src/shader.wgsl"))),
 		});
 
 		//load textures
@@ -636,10 +642,10 @@ impl GraphicsState{
 				wgpu::TextureFormat::Astc{
 					block:AstcBlock::B4x4,
 					channel:AstcChannel::UnormSrgb,
-				}=>&include_bytes!("../images/astc.dds")[..],
-				wgpu::TextureFormat::Etc2Rgb8UnormSrgb=>&include_bytes!("../images/etc2.dds")[..],
-				wgpu::TextureFormat::Bc1RgbaUnormSrgb=>&include_bytes!("../images/bc1.dds")[..],
-				wgpu::TextureFormat::Bgra8UnormSrgb=>&include_bytes!("../images/bgra.dds")[..],
+				}=>&include_bytes!("../../../strafe-client/images/astc.dds")[..],
+				wgpu::TextureFormat::Etc2Rgb8UnormSrgb=>&include_bytes!("../../../strafe-client/images/etc2.dds")[..],
+				wgpu::TextureFormat::Bc1RgbaUnormSrgb=>&include_bytes!("../../../strafe-client/images/bc1.dds")[..],
+				wgpu::TextureFormat::Bgra8UnormSrgb=>&include_bytes!("../../../strafe-client/images/bgra.dds")[..],
 				_=>unreachable!(),
 			};
 
@@ -682,7 +688,7 @@ impl GraphicsState{
 
 		//squid
 		let squid_texture_view={
-			let bytes=include_bytes!("../images/squid.dds");
+			let bytes=include_bytes!("../../../strafe-client/images/squid.dds");
 
 			let image=ddsfile::Dds::read(&mut std::io::Cursor::new(bytes)).unwrap();
 
@@ -864,7 +870,7 @@ impl GraphicsState{
 		&mut self,
 		device:&wgpu::Device,
 		config:&wgpu::SurfaceConfiguration,
-		user_settings:&crate::settings::UserSettings,
+		user_settings:&settings::UserSettings,
 	){
 		self.depth_view=Self::create_depth_texture(config,device);
 		self.camera.screen_size=glam::uvec2(config.width,config.height);
@@ -875,7 +881,7 @@ impl GraphicsState{
 		view:&wgpu::TextureView,
 		device:&wgpu::Device,
 		queue:&wgpu::Queue,
-		frame_state:crate::session::FrameState,
+		frame_state:session::FrameState,
 	){
 		//TODO:use scheduled frame times to create beautiful smoothing simulation physics extrapolation assuming no input
 
diff --git a/engine/graphics/src/lib.rs b/engine/graphics/src/lib.rs
new file mode 100644
index 00000000..3e30a981
--- /dev/null
+++ b/engine/graphics/src/lib.rs
@@ -0,0 +1,2 @@
+pub mod model;
+pub mod graphics;
diff --git a/strafe-client/src/model_graphics.rs b/engine/graphics/src/model.rs
similarity index 100%
rename from strafe-client/src/model_graphics.rs
rename to engine/graphics/src/model.rs
diff --git a/engine/physics/Cargo.toml b/engine/physics/Cargo.toml
new file mode 100644
index 00000000..03e63134
--- /dev/null
+++ b/engine/physics/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "strafesnet_physics"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+arrayvec = "0.7.6"
+glam = "0.29.0"
+id = { version = "0.1.0", registry = "strafesnet" }
+strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
diff --git a/engine/physics/LICENSE b/engine/physics/LICENSE
new file mode 100644
index 00000000..f6ff6bc0
--- /dev/null
+++ b/engine/physics/LICENSE
@@ -0,0 +1,8 @@
+/*******************************************************
+* Copyright (C) 2023-2024 Rhys Lloyd <krakow20@gmail.com>
+*
+* This file is part of the StrafesNET bhop/surf client.
+*
+* StrafesNET can not be copied and/or distributed
+* without the express permission of Rhys Lloyd
+*******************************************************/
\ No newline at end of file
diff --git a/strafe-client/src/body.rs b/engine/physics/src/body.rs
similarity index 98%
rename from strafe-client/src/body.rs
rename to engine/physics/src/body.rs
index 6f7f7692..102b607f 100644
--- a/strafe-client/src/body.rs
+++ b/engine/physics/src/body.rs
@@ -82,7 +82,7 @@ impl<T> Body<T>
 		// a*dt + v
 		self.acceleration.map(|elem|(dt*elem).divide().fix())+self.velocity
 	}
-	pub fn advance_time_ratio_dt(&mut self,dt:crate::model_physics::GigaTime){
+	pub fn advance_time_ratio_dt(&mut self,dt:crate::model::GigaTime){
 		self.position=self.extrapolated_position_ratio_dt(dt);
 		self.velocity=self.extrapolated_velocity_ratio_dt(dt);
 		self.time+=dt.into();
diff --git a/strafe-client/src/face_crawler.rs b/engine/physics/src/face_crawler.rs
similarity index 98%
rename from strafe-client/src/face_crawler.rs
rename to engine/physics/src/face_crawler.rs
index 4b2fab44..b444cb80 100644
--- a/strafe-client/src/face_crawler.rs
+++ b/engine/physics/src/face_crawler.rs
@@ -1,4 +1,4 @@
-use crate::model_physics::{GigaTime,FEV,MeshQuery,DirectedEdge};
+use crate::model::{GigaTime,FEV,MeshQuery,DirectedEdge};
 use strafesnet_common::integer::{Fixed,Ratio,vec3::Vector3};
 use crate::physics::{Time,Body};
 
diff --git a/engine/physics/src/lib.rs b/engine/physics/src/lib.rs
new file mode 100644
index 00000000..8d255ef4
--- /dev/null
+++ b/engine/physics/src/lib.rs
@@ -0,0 +1,6 @@
+mod body;
+mod push_solve;
+mod face_crawler;
+mod model;
+
+pub mod physics;
diff --git a/strafe-client/src/model_physics.rs b/engine/physics/src/model.rs
similarity index 100%
rename from strafe-client/src/model_physics.rs
rename to engine/physics/src/model.rs
diff --git a/strafe-client/src/physics.rs b/engine/physics/src/physics.rs
similarity index 99%
rename from strafe-client/src/physics.rs
rename to engine/physics/src/physics.rs
index 5b7cab27..709efb79 100644
--- a/strafe-client/src/physics.rs
+++ b/engine/physics/src/physics.rs
@@ -1,5 +1,5 @@
 use std::collections::{HashMap,HashSet};
-use crate::model_physics::{self,PhysicsMesh,PhysicsMeshTransform,TransformedMesh,MeshQuery,PhysicsMeshId,PhysicsSubmeshId};
+use crate::model::{self as model_physics,PhysicsMesh,PhysicsMeshTransform,TransformedMesh,MeshQuery,PhysicsMeshId,PhysicsSubmeshId};
 use strafesnet_common::bvh;
 use strafesnet_common::map;
 use strafesnet_common::run;
diff --git a/strafe-client/src/push_solve.rs b/engine/physics/src/push_solve.rs
similarity index 100%
rename from strafe-client/src/push_solve.rs
rename to engine/physics/src/push_solve.rs
diff --git a/engine/session/Cargo.toml b/engine/session/Cargo.toml
new file mode 100644
index 00000000..545f2bc9
--- /dev/null
+++ b/engine/session/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "strafesnet_session"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+glam = "0.29.0"
+replace_with = "0.1.7"
+strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
+strafesnet_physics = { path = "../physics", registry = "strafesnet" }
+strafesnet_settings = { path = "../settings", registry = "strafesnet" }
+strafesnet_snf = { path = "../../lib/snf", registry = "strafesnet" }
diff --git a/engine/session/LICENSE b/engine/session/LICENSE
new file mode 100644
index 00000000..f6ff6bc0
--- /dev/null
+++ b/engine/session/LICENSE
@@ -0,0 +1,8 @@
+/*******************************************************
+* Copyright (C) 2023-2024 Rhys Lloyd <krakow20@gmail.com>
+*
+* This file is part of the StrafesNET bhop/surf client.
+*
+* StrafesNET can not be copied and/or distributed
+* without the express permission of Rhys Lloyd
+*******************************************************/
\ No newline at end of file
diff --git a/engine/session/src/lib.rs b/engine/session/src/lib.rs
new file mode 100644
index 00000000..3bf4fc53
--- /dev/null
+++ b/engine/session/src/lib.rs
@@ -0,0 +1,2 @@
+mod mouse_interpolator;
+pub mod session;
diff --git a/strafe-client/src/mouse_interpolator.rs b/engine/session/src/mouse_interpolator.rs
similarity index 100%
rename from strafe-client/src/mouse_interpolator.rs
rename to engine/session/src/mouse_interpolator.rs
diff --git a/strafe-client/src/session.rs b/engine/session/src/session.rs
similarity index 97%
rename from strafe-client/src/session.rs
rename to engine/session/src/session.rs
index 18bad1e3..5b1fa0df 100644
--- a/strafe-client/src/session.rs
+++ b/engine/session/src/session.rs
@@ -14,8 +14,8 @@ use strafesnet_common::timer::{Scaled,Timer};
 use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime};
 
 use crate::mouse_interpolator::{MouseInterpolator,StepInstruction,Instruction as MouseInterpolatorInstruction};
-use crate::physics::{PhysicsContext,PhysicsData};
-use crate::settings::UserSettings;
+use strafesnet_physics::physics::{self,PhysicsContext,PhysicsData};
+use strafesnet_settings::settings::UserSettings;
 
 pub enum Instruction<'a>{
 	Input(SessionInputInstruction),
@@ -57,19 +57,19 @@ pub enum SessionPlaybackInstruction{
 }
 
 pub struct FrameState{
-	pub body:crate::physics::Body,
-	pub camera:crate::physics::PhysicsCamera,
+	pub body:physics::Body,
+	pub camera:physics::PhysicsCamera,
 	pub time:PhysicsTime,
 }
 
 pub struct Simulation{
 	timer:Timer<Scaled<SessionTimeInner,PhysicsTimeInner>>,
-	physics:crate::physics::PhysicsState,
+	physics:physics::PhysicsState,
 }
 impl Simulation{
 	pub const fn new(
 		timer:Timer<Scaled<SessionTimeInner,PhysicsTimeInner>>,
-		physics:crate::physics::PhysicsState,
+		physics:physics::PhysicsState,
 	)->Self{
 		Self{
 			timer,
@@ -153,7 +153,7 @@ pub struct Session{
 	mouse_interpolator:crate::mouse_interpolator::MouseInterpolator,
 	view_state:ViewState,
 	//gui:GuiState
-	geometry_shared:crate::physics::PhysicsData,
+	geometry_shared:physics::PhysicsData,
 	simulation:Simulation,
 	// below fields not included in lite session
 	recording:Recording,
@@ -299,7 +299,7 @@ impl InstructionConsumer<Instruction<'_>> for Session{
 						std::thread::spawn(move ||{
 							std::fs::create_dir_all("replays").unwrap();
 							let file=std::fs::File::create(file_name).unwrap();
-							strafesnet_snf::bot::write_bot(std::io::BufWriter::new(file),crate::physics::VERSION.get(),replay.recording.instructions).unwrap();
+							strafesnet_snf::bot::write_bot(std::io::BufWriter::new(file),physics::VERSION.get(),replay.recording.instructions).unwrap();
 							println!("Finished writing bot file!");
 						});
 					},
diff --git a/engine/settings/Cargo.toml b/engine/settings/Cargo.toml
new file mode 100644
index 00000000..8bf59f07
--- /dev/null
+++ b/engine/settings/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "strafesnet_settings"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+configparser = "3.0.2"
+glam = "0.29.0"
+strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
diff --git a/engine/settings/LICENSE b/engine/settings/LICENSE
new file mode 100644
index 00000000..f6ff6bc0
--- /dev/null
+++ b/engine/settings/LICENSE
@@ -0,0 +1,8 @@
+/*******************************************************
+* Copyright (C) 2023-2024 Rhys Lloyd <krakow20@gmail.com>
+*
+* This file is part of the StrafesNET bhop/surf client.
+*
+* StrafesNET can not be copied and/or distributed
+* without the express permission of Rhys Lloyd
+*******************************************************/
\ No newline at end of file
diff --git a/engine/settings/src/lib.rs b/engine/settings/src/lib.rs
new file mode 100644
index 00000000..6e98cefd
--- /dev/null
+++ b/engine/settings/src/lib.rs
@@ -0,0 +1 @@
+pub mod settings;
diff --git a/strafe-client/src/settings.rs b/engine/settings/src/settings.rs
similarity index 100%
rename from strafe-client/src/settings.rs
rename to engine/settings/src/settings.rs
diff --git a/strafe-client/Cargo.toml b/strafe-client/Cargo.toml
index 792a679c..091676b3 100644
--- a/strafe-client/Cargo.toml
+++ b/strafe-client/Cargo.toml
@@ -15,19 +15,17 @@ source = ["dep:strafesnet_deferred_loader", "dep:strafesnet_bsp_loader"]
 roblox = ["dep:strafesnet_deferred_loader", "dep:strafesnet_rbx_loader"]
 
 [dependencies]
-arrayvec = "0.7.6"
-bytemuck = { version = "1.13.1", features = ["derive"] }
-configparser = "3.0.2"
-ddsfile = "0.5.1"
 glam = "0.29.0"
-id = { version = "0.1.0", registry = "strafesnet" }
 parking_lot = "0.12.1"
 pollster = "0.4.0"
-replace_with = "0.1.7"
 strafesnet_bsp_loader = { path = "../lib/bsp_loader", registry = "strafesnet", optional = true }
 strafesnet_common = { path = "../lib/common", registry = "strafesnet" }
 strafesnet_deferred_loader = { path = "../lib/deferred_loader", features = ["legacy"], registry = "strafesnet", optional = true }
+strafesnet_graphics = { path = "../engine/graphics", registry = "strafesnet" }
+strafesnet_physics = { path = "../engine/physics", registry = "strafesnet" }
 strafesnet_rbx_loader = { path = "../lib/rbx_loader", registry = "strafesnet", optional = true }
+strafesnet_session = { path = "../engine/session", registry = "strafesnet" }
+strafesnet_settings = { path = "../engine/settings", registry = "strafesnet" }
 strafesnet_snf = { path = "../lib/snf", registry = "strafesnet", optional = true }
 wgpu = "24.0.0"
 winit = "0.30.7"
diff --git a/strafe-client/src/graphics_worker.rs b/strafe-client/src/graphics_worker.rs
index 76d6ecaa..b13f515c 100644
--- a/strafe-client/src/graphics_worker.rs
+++ b/strafe-client/src/graphics_worker.rs
@@ -1,7 +1,11 @@
+use strafesnet_graphics::graphics;
+use strafesnet_session::session;
+use strafesnet_settings::settings;
+
 pub enum Instruction{
-	Render(crate::session::FrameState),
-	//UpdateModel(crate::graphics::GraphicsModelUpdate),
-	Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
+	Render(session::FrameState),
+	//UpdateModel(graphics::GraphicsModelUpdate),
+	Resize(winit::dpi::PhysicalSize<u32>,settings::UserSettings),
 	ChangeMap(strafesnet_common::map::CompleteMap),
 }
 
@@ -15,7 +19,7 @@ WorkerDescription{
 //up to three frames in flight, dropping new frame requests when all three are busy, and dropping output frames when one renders out of order
 
 pub fn new(
-	mut graphics:crate::graphics::GraphicsState,
+	mut graphics:graphics::GraphicsState,
 	mut config:wgpu::SurfaceConfiguration,
 	surface:wgpu::Surface,
 	device:wgpu::Device,
diff --git a/strafe-client/src/main.rs b/strafe-client/src/main.rs
index 968c6309..65beb0f0 100644
--- a/strafe-client/src/main.rs
+++ b/strafe-client/src/main.rs
@@ -1,20 +1,10 @@
-mod body;
 mod file;
 mod setup;
 mod window;
 mod worker;
-mod physics;
-mod session;
-mod graphics;
-mod settings;
-mod push_solve;
-mod face_crawler;
 mod compat_worker;
-mod model_physics;
-mod model_graphics;
 mod physics_worker;
 mod graphics_worker;
-mod mouse_interpolator;
 
 const TITLE:&'static str=concat!("Strafe Client v",env!("CARGO_PKG_VERSION"));
 
diff --git a/strafe-client/src/physics_worker.rs b/strafe-client/src/physics_worker.rs
index 40bfaf46..a597c03a 100644
--- a/strafe-client/src/physics_worker.rs
+++ b/strafe-client/src/physics_worker.rs
@@ -1,6 +1,7 @@
 use crate::graphics_worker::Instruction as GraphicsInstruction;
-use crate::session::{
-	Session,Simulation,SessionInputInstruction,SessionControlInstruction,SessionPlaybackInstruction,
+use strafesnet_settings::settings;
+use strafesnet_session::session::{
+	Session,Simulation,SessionInputInstruction,SessionControlInstruction,SessionPlaybackInstruction,ImplicitModeInstruction,
 	Instruction as SessionInstruction,
 };
 use strafesnet_common::instruction::{TimedInstruction,InstructionConsumer};
@@ -20,9 +21,9 @@ pub enum Instruction{
 
 pub fn new<'a>(
 	mut graphics_worker:crate::compat_worker::INWorker<'a,crate::graphics_worker::Instruction>,
-	user_settings:crate::settings::UserSettings,
+	user_settings:settings::UserSettings,
 )->crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction,SessionTimeInner>>{
-	let physics=crate::physics::PhysicsState::default();
+	let physics=strafesnet_physics::physics::PhysicsState::default();
 	let timer=Timer::unpaused(SessionTime::ZERO,PhysicsTime::ZERO);
 	let simulation=Simulation::new(timer,physics);
 	let mut session=Session::new(
@@ -67,7 +68,7 @@ pub fn new<'a>(
 			},
 			Instruction::ChangeMap(complete_map)=>{
 				run_session_instruction!(ins.time,SessionInstruction::ChangeMap(&complete_map));
-				run_session_instruction!(ins.time,SessionInstruction::Input(SessionInputInstruction::Mode(crate::session::ImplicitModeInstruction::ResetAndSpawn(strafesnet_common::gameplay_modes::ModeId::MAIN,strafesnet_common::gameplay_modes::StageId::FIRST))));
+				run_session_instruction!(ins.time,SessionInstruction::Input(SessionInputInstruction::Mode(ImplicitModeInstruction::ResetAndSpawn(strafesnet_common::gameplay_modes::ModeId::MAIN,strafesnet_common::gameplay_modes::StageId::FIRST))));
 				run_graphics_worker_instruction!(GraphicsInstruction::ChangeMap(complete_map));
 			},
 			Instruction::LoadReplay(bot)=>{
diff --git a/strafe-client/src/setup.rs b/strafe-client/src/setup.rs
index acb51b3e..e54f41b0 100644
--- a/strafe-client/src/setup.rs
+++ b/strafe-client/src/setup.rs
@@ -17,9 +17,6 @@ fn required_downlevel_capabilities()->wgpu::DownlevelCapabilities{
 		..wgpu::DownlevelCapabilities::default()
 	}
 }
-pub fn required_limits()->wgpu::Limits{
-	wgpu::Limits::default()
-}
 
 struct SetupContextPartial1{
 	backends:wgpu::Backends,
@@ -130,7 +127,7 @@ impl<'a> SetupContextPartial3<'a>{
 		let required_features=required_features();
 
 		// Make sure we use the texture resolution limits from the adapter, so we can support images the size of the surface.
-		let needed_limits=required_limits().using_resolution(self.adapter.limits());
+		let needed_limits=strafesnet_graphics::graphics::required_limits().using_resolution(self.adapter.limits());
 
 		let trace_dir=std::env::var("WGPU_TRACE");
 		let (device, queue)=pollster::block_on(self.adapter
diff --git a/strafe-client/src/window.rs b/strafe-client/src/window.rs
index b9a73f12..65097b4f 100644
--- a/strafe-client/src/window.rs
+++ b/strafe-client/src/window.rs
@@ -3,7 +3,8 @@ use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInn
 use strafesnet_common::physics::{MiscInstruction,SetControlInstruction};
 use crate::file::LoadFormat;
 use crate::physics_worker::Instruction as PhysicsWorkerInstruction;
-use crate::session::{SessionInputInstruction,SessionControlInstruction,SessionPlaybackInstruction};
+use strafesnet_session::session::{self,SessionInputInstruction,SessionControlInstruction,SessionPlaybackInstruction};
+use strafesnet_settings::settings;
 
 pub enum Instruction{
 	Resize(winit::dpi::PhysicalSize<u32>),
@@ -150,7 +151,7 @@ impl WindowContext<'_>{
 								"R"|"r"=>s.then(||{
 									//mouse needs to be reset since the position is absolute
 									self.mouse_pos=glam::DVec2::ZERO;
-									SessionInstructionSubset::Input(SessionInputInstruction::Mode(crate::session::ImplicitModeInstruction::ResetAndRestart))
+									SessionInstructionSubset::Input(SessionInputInstruction::Mode(session::ImplicitModeInstruction::ResetAndRestart))
 								}),
 								"F"|"f"=>input_misc!(PracticeFly,s),
 								"B"|"b"=>session_ctrl!(CopyRecordingIntoReplayAndSpectate,s),
@@ -210,9 +211,9 @@ pub fn worker<'a>(
 	setup_context:crate::setup::SetupContext<'a>,
 )->crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction,SessionTimeInner>>{
 	// WindowContextSetup::new
-	let user_settings=crate::settings::read_user_settings();
+	let user_settings=settings::read_user_settings();
 
-	let mut graphics=crate::graphics::GraphicsState::new(&setup_context.device,&setup_context.queue,&setup_context.config);
+	let mut graphics=strafesnet_graphics::graphics::GraphicsState::new(&setup_context.device,&setup_context.queue,&setup_context.config);
 	graphics.load_user_settings(&user_settings);
 
 	//WindowContextSetup::into_context
diff --git a/strafe-client/src/worker.rs b/strafe-client/src/worker.rs
index 52bb3516..1cd66033 100644
--- a/strafe-client/src/worker.rs
+++ b/strafe-client/src/worker.rs
@@ -176,7 +176,7 @@ impl<'a,Task:Send+'a> INWorker<'a,Task>{
 #[cfg(test)]
 mod test{
 	use super::{thread,QRWorker};
-	type Body=crate::physics::Body;
+	type Body=strafesnet_physics::physics::Body;
 	use strafesnet_common::{integer,instruction};
 	#[test]//How to run this test with printing: cargo test --release -- --nocapture
 	fn test_worker() {