diff --git a/lib/common/src/bvh.rs b/lib/common/src/bvh.rs
index 66d0b2e..05b7cf3 100644
--- a/lib/common/src/bvh.rs
+++ b/lib/common/src/bvh.rs
@@ -31,11 +31,6 @@ impl<T> Default for BvhNode<T>{
 		}
 	}
 }
-pub struct BvhWeightNode<W,T>{
-	content:RecursiveContent<BvhWeightNode<W,T>,T>,
-	weight:W,
-	aabb:Aabb,
-}
 
 impl<T> BvhNode<T>{
 	pub fn the_tester<F:FnMut(&T)>(&self,aabb:&Aabb,f:&mut F){
@@ -52,44 +47,8 @@ impl<T> BvhNode<T>{
 			},
 		}
 	}
-	pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
-		match self.content{
-			RecursiveContent::Leaf(model)=>f(model),
-			RecursiveContent::Branch(children)=>for child in children{
-				child.into_visitor(f)
-			},
-		}
-	}
-	pub fn weigh_contents<W:Copy+std::iter::Sum<W>,F:Fn(&T)->W>(self,f:&F)->BvhWeightNode<W,T>{
-		match self.content{
-			RecursiveContent::Leaf(model)=>BvhWeightNode{
-				weight:f(&model),
-				content:RecursiveContent::Leaf(model),
-				aabb:self.aabb,
-			},
-			RecursiveContent::Branch(children)=>{
-				let branch:Vec<BvhWeightNode<W,T>>=children.into_iter().map(|child|
-					child.weigh_contents(f)
-				).collect();
-				BvhWeightNode{
-					weight:branch.iter().map(|node|node.weight).sum(),
-					content:RecursiveContent::Branch(branch),
-					aabb:self.aabb,
-				}
-			},
-		}
-	}
-}
-
-impl <W,T> BvhWeightNode<W,T>{
-	pub const fn weight(&self)->&W{
-		&self.weight
-	}
-	pub const fn aabb(&self)->&Aabb{
-		&self.aabb
-	}
-	pub fn into_content(self)->RecursiveContent<BvhWeightNode<W,T>,T>{
-		self.content
+	pub fn into_inner(self)->(RecursiveContent<BvhNode<T>,T>,Aabb){
+		(self.content,self.aabb)
 	}
 	pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
 		match self.content{
diff --git a/lib/snf/src/map.rs b/lib/snf/src/map.rs
index c822795..0d91209 100644
--- a/lib/snf/src/map.rs
+++ b/lib/snf/src/map.rs
@@ -6,7 +6,7 @@ use crate::file::BlockId;
 use binrw::{binrw,BinReaderExt,BinWriterExt};
 use strafesnet_common::model;
 use strafesnet_common::aabb::Aabb;
-use strafesnet_common::bvh::BvhNode;
+use strafesnet_common::bvh::{BvhNode,RecursiveContent};
 use strafesnet_common::gameplay_modes;
 
 #[derive(Debug)]
@@ -287,12 +287,60 @@ impl<R:BinReaderExt> StreamableMap<R>{
 	}
 }
 
+// silly redefinition of Bvh for determining the size of subnodes
+// without duplicating work by running weight calculation recursion top down on every node
+pub struct BvhWeightNode<W,T>{
+	content:RecursiveContent<BvhWeightNode<W,T>,T>,
+	weight:W,
+	aabb:Aabb,
+}
+impl <W,T> BvhWeightNode<W,T>{
+	pub const fn weight(&self)->&W{
+		&self.weight
+	}
+	pub const fn aabb(&self)->&Aabb{
+		&self.aabb
+	}
+	pub fn into_content(self)->RecursiveContent<BvhWeightNode<W,T>,T>{
+		self.content
+	}
+	pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
+		match self.content{
+			RecursiveContent::Leaf(model)=>f(model),
+			RecursiveContent::Branch(children)=>for child in children{
+				child.into_visitor(f)
+			},
+		}
+	}
+}
+
+pub fn weigh_contents<T,W:Copy+std::iter::Sum<W>,F:Fn(&T)->W>(node:BvhNode<T>,f:&F)->BvhWeightNode<W,T>{
+	let (content,aabb)=node.into_inner();
+	match content{
+		RecursiveContent::Leaf(model)=>BvhWeightNode{
+			weight:f(&model),
+			content:RecursiveContent::Leaf(model),
+			aabb,
+		},
+		RecursiveContent::Branch(children)=>{
+			let branch:Vec<BvhWeightNode<W,T>>=children.into_iter().map(|child|
+				weigh_contents(child,f)
+			).collect();
+			BvhWeightNode{
+				weight:branch.iter().map(|node|node.weight).sum(),
+				content:RecursiveContent::Branch(branch),
+				aabb,
+			}
+		},
+	}
+}
+
 const BVH_NODE_MAX_WEIGHT:usize=64*1024;//64 kB
 fn collect_spacial_blocks(
 	block_location:&mut Vec<u64>,
 	block_headers:&mut Vec<SpacialBlockHeader>,
 	sequential_block_data:&mut std::io::Cursor<&mut Vec<u8>>,
-	bvh_node:strafesnet_common::bvh::BvhWeightNode<usize,(model::ModelId,newtypes::model::Model)>
+	bvh_node:BvhWeightNode<usize,(model::ModelId,newtypes::model::Model)>
 )->Result<(),Error>{
 	//inspect the node weights top-down.
 	//When a node weighs less than the limit,
@@ -342,7 +390,7 @@ pub fn write_map<W:BinWriterExt>(mut writer:W,map:strafesnet_common::map::Comple
 		}
 		Ok(((model::ModelId::new(model_id as u32),model.into()),aabb))
 	}).collect::<Result<Vec<_>,_>>()?;
-	let bvh=strafesnet_common::bvh::generate_bvh(boxen).weigh_contents(&|_|std::mem::size_of::<newtypes::model::Model>());
+	let bvh=weigh_contents(strafesnet_common::bvh::generate_bvh(boxen),&|_|std::mem::size_of::<newtypes::model::Model>());
 	//build blocks
 	//block location is initialized with two values
 	//the first value represents the location of the first byte after the file header