diff --git a/lib/bsp_loader/src/bsp.rs b/lib/bsp_loader/src/bsp.rs
index b625774..72558e6 100644
--- a/lib/bsp_loader/src/bsp.rs
+++ b/lib/bsp_loader/src/bsp.rs
@@ -41,7 +41,9 @@ pub fn convert<'a>(
 	//figure out real attributes later
 	let mut unique_attributes=Vec::new();
 	unique_attributes.push(gameplay_attributes::CollisionAttributes::Decoration);
+	unique_attributes.push(gameplay_attributes::CollisionAttributes::contact_default());
 	const ATTRIBUTE_DECORATION:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(0);
+	const ATTRIBUTE_CONTACT_DEFAULT:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(1);
 
 	//declare all prop models to Loader
 	let prop_models=bsp.static_props().map(|prop|{
@@ -67,7 +69,7 @@ pub fn convert<'a>(
 
 	//the generated MeshIds in here will collide with the Loader Mesh Ids
 	//but I can't think of a good workaround other than just remapping one later.
-	let world_meshes:Vec<model::Mesh>=bsp.models().map(|world_model|{
+	let mut world_meshes:Vec<model::Mesh>=bsp.models().map(|world_model|{
 		let mut mb=model::MeshBuilder::new();
 
 		let color=mb.acquire_color_id(glam::Vec4::ONE);
@@ -118,6 +120,41 @@ pub fn convert<'a>(
 		mb.build(polygon_groups,graphics_groups,vec![])
 	}).collect();
 
+	let brush_mesh_start_idx=world_meshes.len();
+	for brush in &bsp.brushes{
+		let brush_start_idx=brush.brush_side as usize;
+		if let Some(sides)=bsp.brush_sides.get(brush_start_idx..brush_start_idx+brush.num_brush_sides as usize){
+			let mut mb=model::MeshBuilder::new();
+			let color=mb.acquire_color_id(glam::Vec4::ONE);
+			let tex=mb.acquire_tex_id(glam::Vec2::ZERO);
+			let mut polygon_list=Vec::new();
+			for side in sides{
+				if let Some(displacement)=bsp.displacement(side.displacement_info as usize){
+					if let Some(face)=displacement.face(){
+						let normal=mb.acquire_normal_id(valve_transform(face.normal().into()));
+						polygon_list.push(face.vertices().map(|vertex|{
+							let vertex_xyz=vertex.position.into();
+							let pos=mb.acquire_pos_id(valve_transform(vertex_xyz));
+							mb.acquire_vertex_id(model::IndexedVertex{
+								pos,
+								tex,
+								normal,
+								color,
+							})
+						}).collect());
+					}
+				}
+			}
+			if !polygon_list.is_empty(){
+				let polygon_groups=model::PolygonGroup::PolygonList(model::PolygonList::new(polygon_list));
+				let physics_groups=vec![model::IndexedPhysicsGroup{
+					groups:vec![model::PolygonGroupId::new(0)],
+				}];
+				world_meshes.push(mb.build(vec![polygon_groups],vec![],physics_groups));
+			}
+		}
+	}
+
 	let world_models:Vec<model::Model>=
 	//one instance of the main world mesh
 	std::iter::once((
@@ -151,7 +188,18 @@ pub fn convert<'a>(
 			valve_transform(model_origin.into())
 		),
 		color:(glam::Vec3::from_array([r as f32,g as f32,b as f32])/255.0).extend(1.0),
-	}).collect();
+	}).chain(
+		// physics models
+		(brush_mesh_start_idx..world_meshes.len()).map(|mesh_id|model::Model{
+			mesh:model::MeshId::new(mesh_id as u32),
+			attributes:ATTRIBUTE_CONTACT_DEFAULT,
+			transform:integer::Planar64Affine3::new(
+				integer::mat3::identity(),
+				integer::vec3::ZERO,
+			),
+			color:glam::Vec4::ONE,
+		})
+	).collect();
 
 	PartialMap1{
 		attributes:unique_attributes,