diff --git a/src/bsp.rs b/src/bsp.rs
index b939774..de7d161 100644
--- a/src/bsp.rs
+++ b/src/bsp.rs
@@ -19,6 +19,11 @@ where
 	unique_attributes.push(gameplay_attributes::CollisionAttributes::contact_default());
 	const TEMP_TOUCH_ME_ATTRIBUTE:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(0);
 
+	//declare all prop models to Loader
+	for prop in bsp.static_props(){
+		acquire_mesh_id(prop.model());
+	}
+
 	//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 (meshes,models):(Vec<model::Mesh>,Vec<model::Model>)=bsp.models().enumerate().map(|(mesh_id,world_model)|{
@@ -104,131 +109,6 @@ where
 		)
 	}).unzip();
 
-	//dedupe prop models
-	let mut model_dedupe=std::collections::HashSet::new();
-	for prop in bsp.static_props(){
-		model_dedupe.insert(prop.model());
-	}
-
-	//generate unique meshes
-	let mut model_map=std::collections::HashMap::with_capacity(model_dedupe.len());
-	let mut prop_models=Vec::new();
-	for model_name in model_dedupe{
-		let model_name_lower=model_name.to_lowercase();
-		//.mdl, .vvd, .dx90.vtx
-		let mut path=std::path::PathBuf::from(model_name_lower.as_str());
-		let file_name=std::path::PathBuf::from(path.file_stem().unwrap());
-		path.pop();
-		path.push(file_name);
-		let mut vvd_path=path.clone();
-		let mut vtx_path=path.clone();
-		vvd_path.set_extension("vvd");
-		vtx_path.set_extension("dx90.vtx");
-		match (bsp.pack.get(model_name_lower.as_str()),bsp.pack.get(vvd_path.as_os_str().to_str().unwrap()),bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())){
-			(Ok(Some(mdl_file)),Ok(Some(vvd_file)),Ok(Some(vtx_file)))=>{
-				match (vmdl::mdl::Mdl::read(mdl_file.as_ref()),vmdl::vvd::Vvd::read(vvd_file.as_ref()),vmdl::vtx::Vtx::read(vtx_file.as_ref())){
-					(Ok(mdl),Ok(vvd),Ok(vtx))=>{
-						let model=vmdl::Model::from_parts(mdl,vtx,vvd);
-						let texture_paths=model.texture_directories();
-						if texture_paths.len()!=1{
-							println!("WARNING: multiple texture paths");
-						}
-						let skin=model.skin_tables().nth(0).unwrap();
-
-						let mut spam_pos=Vec::with_capacity(model.vertices().len());
-						let mut spam_normal=Vec::with_capacity(model.vertices().len());
-						let mut spam_tex=Vec::with_capacity(model.vertices().len());
-						let mut spam_vertices=Vec::with_capacity(model.vertices().len());
-						for (i,vertex) in model.vertices().iter().enumerate(){
-							spam_pos.push(valve_transform(<[f32;3]>::from(vertex.position)));
-							spam_normal.push(valve_transform(<[f32;3]>::from(vertex.normal)));
-							spam_tex.push(glam::Vec2::from_array(vertex.texture_coordinates));
-							spam_vertices.push(model::IndexedVertex{
-								pos:i as u32,
-								tex:i as u32,
-								normal:i as u32,
-								color:0,
-							});
-						}
-
-						let model_id=prop_models.len();
-						model_map.insert(model_name,model_id);
-						prop_models.push(model::Mesh{
-							unique_pos:spam_pos,
-							unique_normal:spam_normal,
-							unique_tex:spam_tex,
-							unique_color:vec![glam::Vec4::ONE],
-							unique_vertices:spam_vertices,
-							groups:model.meshes().map(|mesh|{
-								let texture=if let (Some(texture_path),Some(texture_name))=(texture_paths.get(0),skin.texture(mesh.material_index())){
-									let mut path=std::path::PathBuf::from(texture_path.as_str());
-									path.push(texture_name);
-									let texture_location=path.as_os_str().to_str().unwrap();
-									let texture_id=if let Some(&texture_id)=texture_id_from_name.get(texture_location){
-										texture_id
-									}else{
-										println!("texture! {}",texture_location);
-										let texture_id=name_from_texture_id.len() as u32;
-										texture_id_from_name.insert(texture_location.to_string(),texture_id);
-										name_from_texture_id.push(texture_location.to_string());
-										texture_id
-									};
-									Some(texture_id)
-								}else{
-									None
-								};
-
-								model::IndexedGroup{
-									texture,
-									polys:{
-										//looking at the code, it would seem that the strips are pre-deindexed into triangle lists when calling this function
-										mesh.vertex_strip_indices().map(|strip|{
-											strip.collect::<Vec<usize>>().chunks(3).map(|tri|{
-												model::IndexedPolygon{vertices:vec![tri[0] as u32,tri[1] as u32,tri[2] as u32]}
-											}).collect::<Vec<model::IndexedPolygon>>()
-										}).flatten().collect()
-									},
-								}
-							}).collect(),
-							instances:Vec::new(),
-						});
-					},
-					_=>println!("model_name={} error",model_name),
-				}
-			},
-			_=>println!("no model name={}",model_name),
-		}
-	}
-
-	//generate model instances
-	for prop in bsp.static_props(){
-		let placement=prop.as_prop_placement();
-		if let Some(&model_index)=model_map.get(placement.model){
-			prop_models[model_index].instances.push(model::ModelInstance{
-				transform:integer::Planar64Affine3::new(
-					integer::Planar64Mat3::try_from(
-						glam::Mat3A::from_diagonal(glam::Vec3::splat(placement.scale))
-						//TODO: figure this out
-						*glam::Mat3A::from_quat(glam::Quat::from_xyzw(
-							placement.rotation.v.x,//b
-							placement.rotation.v.y,//c
-							placement.rotation.v.z,//d
-							placement.rotation.s,//a
-						))
-					).unwrap(),
-					valve_transform(<[f32;3]>::from(placement.origin)),
-				),
-				attributes:model::CollisionAttributes::Decoration,
-				..Default::default()
-			});
-		}else{
-			//println!("model not found {}",placement.model);
-		}
-	}
-
-	//actually add the prop models
-	prop_models.append(&mut models);
-
 	map::CompleteMap{
 		attributes:unique_attributes,
 		meshes,