diff --git a/lib/bsp_loader/src/lib.rs b/lib/bsp_loader/src/lib.rs
index 1021b03..9258df7 100644
--- a/lib/bsp_loader/src/lib.rs
+++ b/lib/bsp_loader/src/lib.rs
@@ -45,6 +45,7 @@ impl From<loader::MeshError> for LoadError{
 }
 pub struct Bsp{
 	bsp:vbsp::Bsp,
+	case_folded_file_names:std::collections::HashMap<String,String>,
 }
 impl AsRef<vbsp::Bsp> for Bsp{
 	fn as_ref(&self)->&vbsp::Bsp{
@@ -62,11 +63,21 @@ pub fn read<R:std::io::Read>(mut input:R)->Result<Bsp,ReadError>{
 }
 impl Bsp{
 	pub fn new(bsp:vbsp::Bsp)->Self{
+		let case_folded_file_names=bsp.pack.clone().into_zip().lock().unwrap().file_names().map(|s|{
+			(s.to_lowercase(),s.to_owned())
+		}).collect();
 		Self{
 			bsp,
+			case_folded_file_names,
 		}
 	}
-	pub fn to_snf(&self,failure_mode:LoadFailureMode,vpk_list:&[vpk::VPK])->Result<strafesnet_common::map::CompleteMap,LoadError>{
+	pub fn pack_get(&self,name_lowercase:&str)->Result<Option<Vec<u8>>,vbsp::BspError>{
+		match self.case_folded_file_names.get(name_lowercase){
+			Some(name_folded)=>self.bsp.pack.get(name_folded),
+			None=>Ok(None),
+		}
+	}
+	pub fn to_snf(&self,failure_mode:LoadFailureMode,vpk_list:&[Vpk])->Result<strafesnet_common::map::CompleteMap,LoadError>{
 		let mut texture_deferred_loader=RenderConfigDeferredLoader::new();
 		let mut mesh_deferred_loader=MeshDeferredLoader::new();
 
@@ -89,3 +100,27 @@ impl Bsp{
 		Ok(map)
 	}
 }
+pub struct Vpk{
+	vpk:vpk::VPK,
+	case_folded_file_names:std::collections::HashMap<String,String>,
+}
+impl AsRef<vpk::VPK> for Vpk{
+	fn as_ref(&self)->&vpk::VPK{
+		&self.vpk
+	}
+}
+impl Vpk{
+	pub fn new(vpk:vpk::VPK)->Vpk{
+		let case_folded_file_names=vpk.tree.keys().map(|s|{
+			(s.to_lowercase(),s.to_owned())
+		}).collect();
+		Vpk{
+			vpk,
+			case_folded_file_names,
+		}
+	}
+	pub fn tree_get(&self,name_lowercase:&str)->Option<&vpk::entry::VPKEntry>{
+		let name_folded=self.case_folded_file_names.get(name_lowercase)?;
+		self.vpk.tree.get(name_folded)
+	}
+}
diff --git a/lib/bsp_loader/src/loader.rs b/lib/bsp_loader/src/loader.rs
index 9117bd4..2a83a64 100644
--- a/lib/bsp_loader/src/loader.rs
+++ b/lib/bsp_loader/src/loader.rs
@@ -3,7 +3,7 @@ use std::{borrow::Cow, io::Read};
 use strafesnet_common::model::Mesh;
 use strafesnet_deferred_loader::{loader::Loader,texture::Texture};
 
-use crate::Bsp;
+use crate::{Bsp,Vpk};
 
 #[allow(dead_code)]
 #[derive(Debug)]
@@ -76,7 +76,7 @@ impl From<vbsp::BspError> for MeshError{
 #[derive(Clone,Copy)]
 pub struct BspFinder<'bsp,'vpk>{
 	pub bsp:&'bsp Bsp,
-	pub vpks:&'vpk [vpk::VPK],
+	pub vpks:&'vpk [Vpk],
 }
 impl<'bsp,'vpk> BspFinder<'bsp,'vpk>{
 	pub fn find<'a>(&self,path:&str)->Result<Option<Cow<'a,[u8]>>,vbsp::BspError>
@@ -85,13 +85,13 @@ impl<'bsp,'vpk> BspFinder<'bsp,'vpk>{
 			'vpk:'a,
 	{
 		// search bsp
-		if let Some(data)=self.bsp.as_ref().pack.get(path)?{
+		if let Some(data)=self.bsp.pack_get(path)?{
 			return Ok(Some(Cow::Owned(data)));
 		}
 
 		//search each vpk
 		for vpk in self.vpks{
-			if let Some(vpk_entry)=vpk.tree.get(path){
+			if let Some(vpk_entry)=vpk.tree_get(path){
 				return Ok(Some(vpk_entry.get()?));
 			}
 		}
diff --git a/map-tool/src/source.rs b/map-tool/src/source.rs
index fa481ec..736804b 100644
--- a/map-tool/src/source.rs
+++ b/map-tool/src/source.rs
@@ -228,7 +228,7 @@ enum ExtractTextureError{
 	#[error("Load VMT error {0:?}")]
 	LoadVMT(#[from]LoadVMTError),
 }
-async fn gimme_them_textures(path:&Path,vpk_list:&[vpk::VPK],send_texture:tokio::sync::mpsc::Sender<(Vec<u8>,String)>)->Result<(),ExtractTextureError>{
+async fn gimme_them_textures(path:&Path,vpk_list:&[strafesnet_bsp_loader::Vpk],send_texture:tokio::sync::mpsc::Sender<(Vec<u8>,String)>)->Result<(),ExtractTextureError>{
 	let bsp=vbsp::Bsp::read(tokio::fs::read(path).await?.as_ref())?;
 	let loader_bsp=strafesnet_bsp_loader::Bsp::new(bsp);
 	let bsp=loader_bsp.as_ref();
@@ -323,10 +323,10 @@ async fn convert_texture(texture:Vec<u8>,write_file_name:impl AsRef<Path>)->Resu
 	Ok(())
 }
 
-async fn read_vpks(vpk_paths:Vec<PathBuf>,thread_limit:usize)->Vec<vpk::VPK>{
+async fn read_vpks(vpk_paths:Vec<PathBuf>,thread_limit:usize)->Vec<strafesnet_bsp_loader::Vpk>{
 	futures::stream::iter(vpk_paths).map(|vpk_path|async{
 		// idk why it doesn't want to pass out the errors but this is fatal anyways
-		tokio::task::spawn_blocking(move||vpk::VPK::read(&vpk_path)).await.unwrap().unwrap()
+		tokio::task::spawn_blocking(move||Ok::<_,vpk::Error>(strafesnet_bsp_loader::Vpk::new(vpk::VPK::read(&vpk_path)?))).await.unwrap().unwrap()
 	})
 	.buffer_unordered(thread_limit)
 	.collect().await
@@ -340,11 +340,8 @@ async fn extract_textures(paths:Vec<PathBuf>,vpk_paths:Vec<PathBuf>)->AResult<()
 	)?;
 	let thread_limit=std::thread::available_parallelism()?.get();
 
-	// load vpk list
-	let vpk_list=read_vpks(vpk_paths,thread_limit).await;
-
-	// leak vpk_list for static lifetime?
-	let vpk_list:&[vpk::VPK]=vpk_list.leak();
+	// load vpk list and leak for static lifetime
+	let vpk_list:&[strafesnet_bsp_loader::Vpk]=read_vpks(vpk_paths,thread_limit).await.leak();
 
 	let (send_texture,mut recv_texture)=tokio::sync::mpsc::channel(thread_limit);
 	let mut it=paths.into_iter();
@@ -414,7 +411,7 @@ impl std::fmt::Display for ConvertError{
 }
 impl std::error::Error for ConvertError{}
 
-async fn convert_to_snf(path:&Path,vpk_list:&[vpk::VPK],output_folder:PathBuf)->AResult<()>{
+async fn convert_to_snf(path:&Path,vpk_list:&[strafesnet_bsp_loader::Vpk],output_folder:PathBuf)->AResult<()>{
 	let entire_file=tokio::fs::read(path).await?;
 
 	let bsp=strafesnet_bsp_loader::read(
@@ -437,11 +434,8 @@ async fn source_to_snf(paths:Vec<std::path::PathBuf>,output_folder:PathBuf,vpk_p
 
 	let thread_limit=std::thread::available_parallelism()?.get();
 
-	// load vpk list
-	let vpk_list=read_vpks(vpk_paths,thread_limit).await;
-
-	// leak vpk_list for static lifetime?
-	let vpk_list:&[vpk::VPK]=vpk_list.leak();
+	// load vpk list and leak for static lifetime
+	let vpk_list:&[strafesnet_bsp_loader::Vpk]=read_vpks(vpk_paths,thread_limit).await.leak();
 
 	let mut it=paths.into_iter();
 	static SEM:tokio::sync::Semaphore=tokio::sync::Semaphore::const_new(0);