diff --git a/Cargo.lock b/Cargo.lock
index 218b979..b37fc6e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -299,7 +299,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7d4bca59c20d6f40c2cc0802afbe1e788b89096f61bdf7aeea6bf00f10c2909b"
 dependencies = [
  "array-init",
- "binrw_derive",
+ "binrw_derive 0.14.1",
+ "bytemuck",
+]
+
+[[package]]
+name = "binrw"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81419ff39e6ed10a92a7f125290859776ced35d9a08a665ae40b23e7ca702f30"
+dependencies = [
+ "array-init",
+ "binrw_derive 0.15.0",
  "bytemuck",
 ]
 
@@ -310,12 +321,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d8ba42866ce5bced2645bfa15e97eef2c62d2bdb530510538de8dd3d04efff3c"
 dependencies = [
  "either",
- "owo-colors",
+ "owo-colors 3.5.0",
  "proc-macro2",
  "quote",
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "binrw_derive"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "376404e55ec40d0d6f8b4b7df3f87b87954bd987f0cf9a7207ea3b6ea5c9add4"
+dependencies = [
+ "either",
+ "owo-colors 4.2.1",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
 [[package]]
 name = "bit-set"
 version = "0.8.0"
@@ -2636,6 +2660,12 @@ version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
 
+[[package]]
+name = "owo-colors"
+version = "4.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec"
+
 [[package]]
 name = "parking_lot"
 version = "0.12.3"
@@ -3104,11 +3134,11 @@ dependencies = [
 
 [[package]]
 name = "rbx_mesh"
-version = "0.3.1"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36372fd7feb6d3c5780d2ada39d1397be9e196ddfbb23ba1d84e7a75cf790adb"
+checksum = "97a6c63d7c29088ce8114b7c76ef401d9c4e33d3fa1c15a72d7ba6832b9c6c12"
 dependencies = [
- "binrw",
+ "binrw 0.15.0",
  "lazy-regex",
 ]
 
@@ -3817,7 +3847,7 @@ dependencies = [
 name = "strafesnet_snf"
 version = "0.3.1"
 dependencies = [
- "binrw",
+ "binrw 0.14.1",
  "id",
  "strafesnet_common",
 ]
@@ -4339,7 +4369,7 @@ checksum = "fdab0507169ff47ea95acab2d08d91c7a31455e272b134879757d19c87075cb1"
 dependencies = [
  "ahash",
  "arrayvec",
- "binrw",
+ "binrw 0.14.1",
  "bitflags 2.9.1",
  "bv",
  "itertools 0.14.0",
@@ -4359,7 +4389,7 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5407a8696cc6de4e9464595c7eb0ee9967008c68b8c156dd465733be28bc16eb"
 dependencies = [
- "binrw",
+ "binrw 0.14.1",
  "cgmath",
  "serde",
  "thiserror 2.0.12",
@@ -4457,7 +4487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e041d0558b49723e4fd634d93042329140e6ec1d6c4100b538a018b78bb1fa05"
 dependencies = [
  "ahash",
- "binrw",
+ "binrw 0.14.1",
  "thiserror 2.0.12",
 ]
 
diff --git a/lib/rbx_loader/Cargo.toml b/lib/rbx_loader/Cargo.toml
index 6c5b06e..6f437d5 100644
--- a/lib/rbx_loader/Cargo.toml
+++ b/lib/rbx_loader/Cargo.toml
@@ -15,7 +15,7 @@ glam = "0.30.0"
 lazy-regex = "3.1.0"
 rbx_binary  = { version = "1.1.0-sn4", registry = "strafesnet" }
 rbx_dom_weak =  { version = "3.1.0-sn4", registry = "strafesnet", features = ["instance-userdata"] }
-rbx_mesh = "0.3.1"
+rbx_mesh = "0.4.0"
 rbx_reflection = "5.0.0"
 rbx_reflection_database = "1.0.0"
 rbx_xml  = { version = "1.1.0-sn4", registry = "strafesnet" }
diff --git a/lib/rbx_loader/src/mesh.rs b/lib/rbx_loader/src/mesh.rs
index 74c12af..b8bf55a 100644
--- a/lib/rbx_loader/src/mesh.rs
+++ b/lib/rbx_loader/src/mesh.rs
@@ -154,7 +154,7 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<MeshWithS
 		}) as u32)
 	};
 	match rbx_mesh::read_versioned(roblox_mesh_bytes.cursor()).map_err(Error::RbxMesh)?{
-		rbx_mesh::mesh::VersionedMesh::Version1(mesh)=>{
+		rbx_mesh::mesh::Mesh::V1(mesh)=>{
 			let color_id=acquire_color_id([1.0f32;4]);
 			polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(mesh.vertices.chunks_exact(3).map(|trip|{
 				let mut ingest_vertex1=|vertex:&rbx_mesh::mesh::Vertex1|Ok(acquire_vertex_id(IndexedVertex{
@@ -166,7 +166,7 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<MeshWithS
 				Ok(vec![ingest_vertex1(&trip[0])?,ingest_vertex1(&trip[1])?,ingest_vertex1(&trip[2])?])
 			}).collect::<Result<_,_>>()?)));
 		},
-		rbx_mesh::mesh::VersionedMesh::Version2(mesh)=>{
+		rbx_mesh::mesh::Mesh::V2(mesh)=>{
 			let vertex_id_map=match mesh.header.sizeof_vertex{
 				rbx_mesh::mesh::SizeOfVertex2::Truncated=>{
 					//pick white and make all the vertices white
@@ -180,7 +180,7 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<MeshWithS
 				vec![vertex_id_map[&face.0],vertex_id_map[&face.1],vertex_id_map[&face.2]]
 			).collect())));
 		},
-		rbx_mesh::mesh::VersionedMesh::Version3(mesh)=>{
+		rbx_mesh::mesh::Mesh::V3(mesh)=>{
 			let vertex_id_map=match mesh.header.sizeof_vertex{
 				rbx_mesh::mesh::SizeOfVertex2::Truncated=>{
 					let color_id=acquire_color_id([1.0f32;4]);
@@ -190,13 +190,13 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<MeshWithS
 			}?;
 			ingest_faces2_lods3(&mut polygon_groups,&vertex_id_map,&mesh.faces,&mesh.lods);
 		},
-		rbx_mesh::mesh::VersionedMesh::Version4(mesh)=>{
+		rbx_mesh::mesh::Mesh::V4(mesh)=>{
 			let vertex_id_map=ingest_vertices2(
 				mesh.vertices,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,&mut acquire_color_id,&mut acquire_vertex_id
 			)?;
 			ingest_faces2_lods3(&mut polygon_groups,&vertex_id_map,&mesh.faces,&mesh.lods);
 		},
-		rbx_mesh::mesh::VersionedMesh::Version5(mesh)=>{
+		rbx_mesh::mesh::Mesh::V5(mesh)=>{
 			let vertex_id_map=ingest_vertices2(
 				mesh.vertices,&mut acquire_pos_id,&mut acquire_tex_id,&mut acquire_normal_id,&mut acquire_color_id,&mut acquire_vertex_id
 			)?;
diff --git a/lib/rbx_loader/src/union.rs b/lib/rbx_loader/src/union.rs
index f11f375..f6829a2 100644
--- a/lib/rbx_loader/src/union.rs
+++ b/lib/rbx_loader/src/union.rs
@@ -81,8 +81,8 @@ pub fn convert(
 		).map_err(Error::RobloxMeshData)?;
 		let graphics_mesh=match mesh_data{
 			rbx_mesh::mesh_data::MeshData::CSGK(_)=>return Err(Error::Block),
-			rbx_mesh::mesh_data::MeshData::CSGMDL(rbx_mesh::mesh_data::CSGMDL::CSGMDL2(mesh_data2))=>mesh_data2.mesh,
-			rbx_mesh::mesh_data::MeshData::CSGMDL(rbx_mesh::mesh_data::CSGMDL::CSGMDL4(mesh_data4))=>mesh_data4.mesh,
+			rbx_mesh::mesh_data::MeshData::CSGMDL(rbx_mesh::mesh_data::CSGMDL::V2(mesh_data2))=>mesh_data2.mesh,
+			rbx_mesh::mesh_data::MeshData::CSGMDL(rbx_mesh::mesh_data::CSGMDL::V4(mesh_data4))=>mesh_data4.mesh,
 		};
 		//autoscale to size, idk what roblox is doing with the graphics mesh size
 		let mut pos_min=glam::Vec3::MAX;
@@ -153,10 +153,13 @@ pub fn convert(
 			// have not seen this format in practice
 			|rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Block)
 			=>return Err(Error::Block),
-			rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Meshes(meshes))
+			rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::V3(meshes))
+			|rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::V5(meshes))
+			=>meshes.meshes,
+			rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::V6(meshes))
+			=>vec![meshes.mesh],
+			rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::V7(meshes))
 			=>meshes.meshes,
-			rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::PhysicsInfoMesh(pim))
-			=>vec![pim.mesh],
 		};
 		let physics_convex_meshes_it=physics_convex_meshes.into_iter().map(|mesh|{
 			// this can be factored out of the loop but I am lazy