diff --git a/engine/physics/src/body.rs b/engine/physics/src/body.rs
index e3fd5b893..568cf659e 100644
--- a/engine/physics/src/body.rs
+++ b/engine/physics/src/body.rs
@@ -42,12 +42,12 @@ impl<T> Body<T>
 	pub fn extrapolated_position(&self,time:Time<T>)->Planar64Vec3{
 		let dt=time-self.time;
 		self.position
-		+(self.velocity*dt).map(|elem|elem.divide().fix_1())
-		+self.acceleration.map(|elem|(dt*dt*elem/2).divide().fix_1())
+		+(self.velocity*dt).map(|elem|elem.divide().clamp_1())
+		+self.acceleration.map(|elem|(dt*dt*elem/2).divide().clamp_1())
 	}
 	pub fn extrapolated_velocity(&self,time:Time<T>)->Planar64Vec3{
 		let dt=time-self.time;
-		self.velocity+(self.acceleration*dt).map(|elem|elem.divide().fix_1())
+		self.velocity+(self.acceleration*dt).map(|elem|elem.divide().clamp_1())
 	}
 	pub fn advance_time(&mut self,time:Time<T>){
 		self.position=self.extrapolated_position(time);
@@ -71,12 +71,12 @@ impl<T> Body<T>
 			D2:Copy,
 			Planar64:core::ops::Mul<D2,Output=N4>,
 			N4:integer::Divide<D2,Output=T1>,
-			T1:integer::Fix<Planar64>,
+			T1:integer::Clamp<Planar64>,
 	{
 		// a*dt^2/2 + v*dt + p
 		// (a*dt/2+v)*dt+p
 		(self.acceleration.map(|elem|dt*elem/2)+self.velocity).map(|elem|dt.mul_ratio(elem))
-		.map(|elem|elem.divide().fix())+self.position
+		.map(|elem|elem.divide().clamp())+self.position
 	}
 	pub fn extrapolated_velocity_ratio_dt<Num,Den,N1,T1>(&self,dt:integer::Ratio<Num,Den>)->Planar64Vec3
 		where
@@ -85,10 +85,10 @@ impl<T> Body<T>
 			Num:core::ops::Mul<Planar64,Output=N1>,
 			Planar64:core::ops::Mul<Den,Output=N1>,
 			N1:integer::Divide<Den,Output=T1>,
-			T1:integer::Fix<Planar64>,
+			T1:integer::Clamp<Planar64>,
 	{
 		// a*dt + v
-		self.acceleration.map(|elem|(dt*elem).divide().fix())+self.velocity
+		self.acceleration.map(|elem|(dt*elem).divide().clamp())+self.velocity
 	}
 	pub fn advance_time_ratio_dt(&mut self,dt:crate::model::GigaTime){
 		self.position=self.extrapolated_position_ratio_dt(dt);
diff --git a/engine/physics/src/face_crawler.rs b/engine/physics/src/face_crawler.rs
index b0df763c1..0d10cb6b8 100644
--- a/engine/physics/src/face_crawler.rs
+++ b/engine/physics/src/face_crawler.rs
@@ -63,7 +63,8 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
 					let &[v0,v1]=mesh.edge_verts(directed_edge_id.as_undirected()).as_ref();
 					//WARNING: d is moved out of the *2 block because of adding two vertices!
 					//WARNING: precision is swept under the rug!
-					for dt in Fixed::<4,128>::zeroes2(n.dot(body.position*2-(mesh.vert(v0)+mesh.vert(v1))).fix_4(),n.dot(body.velocity).fix_4()*2,n.dot(body.acceleration).fix_4()){
+					//wrap for speed
+					for dt in Fixed::<4,128>::zeroes2(n.dot(body.position*2-(mesh.vert(v0)+mesh.vert(v1))).wrap_4(),n.dot(body.velocity).wrap_4()*2,n.dot(body.acceleration).wrap_4()){
 						if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
 							best_time=dt;
 							best_transition=Transition::Next(FEV::Edge(directed_edge_id.as_undirected()),dt);
@@ -84,7 +85,8 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
 					//edge_n gets parity from the order of edge_faces
 					let n=face_n.cross(edge_n)*((i as i64)*2-1);
 					//WARNING yada yada d *2
-					for dt in Fixed::<4,128>::zeroes2(n.dot(delta_pos).fix_4(),n.dot(body.velocity).fix_4()*2,n.dot(body.acceleration).fix_4()){
+					//wrap for speed
+					for dt in Fixed::<4,128>::zeroes2(n.dot(delta_pos).wrap_4(),n.dot(body.velocity).wrap_4()*2,n.dot(body.acceleration).wrap_4()){
 						if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
 							best_time=dt;
 							best_transition=Transition::Next(FEV::Face(edge_face_id),dt);
@@ -98,7 +100,7 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
 					let n=edge_n*(1-2*(i as i64));
 					for dt in Fixed::<2,64>::zeroes2((n.dot(body.position-mesh.vert(vert_id)))*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
 						if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
-							let dt=Ratio::new(dt.num.fix_4(),dt.den.fix_4());
+							let dt=Ratio::new(dt.num.widen_4(),dt.den.widen_4());
 							best_time=dt;
 							best_transition=Transition::Next(FEV::Vert(vert_id),dt);
 							break;
@@ -114,7 +116,7 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
 					let n=-mesh.directed_edge_n(directed_edge_id);
 					for dt in Fixed::<2,64>::zeroes2((n.dot(body.position-mesh.vert(vert_id)))*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
 						if body_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
-							let dt=Ratio::new(dt.num.fix_4(),dt.den.fix_4());
+							let dt=Ratio::new(dt.num.widen_4(),dt.den.widen_4());
 							best_time=dt;
 							best_transition=Transition::Next(FEV::Edge(directed_edge_id.as_undirected()),dt);
 							break;
@@ -129,11 +131,11 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
 	pub fn crawl(mut self,mesh:&M,relative_body:&Body,start_time:Time,time_limit:Time)->CrawlResult<M>{
 		let mut body_time={
 			let r=(start_time-relative_body.time).to_ratio();
-			Ratio::new(r.num.fix_4(),r.den.fix_4())
+			Ratio::new(r.num.widen_4(),r.den.widen_4())
 		};
 		let time_limit={
 			let r=(time_limit-relative_body.time).to_ratio();
-			Ratio::new(r.num.fix_4(),r.den.fix_4())
+			Ratio::new(r.num.widen_4(),r.den.widen_4())
 		};
 		for _ in 0..20{
 			match self.next_transition(body_time,mesh,relative_body,time_limit){
diff --git a/engine/physics/src/model.rs b/engine/physics/src/model.rs
index 0269a857c..2c4aece91 100644
--- a/engine/physics/src/model.rs
+++ b/engine/physics/src/model.rs
@@ -378,8 +378,8 @@ impl TryFrom<&model::Mesh> for PhysicsMesh{
 					}
 					//assume face hash is stable, and there are no flush faces...
 					let face=Face{
-						normal:(normal/len as i64).divide().fix_1(),
-						dot:(dot/(len*len) as i64).fix_1(),
+						normal:(normal/len as i64).divide().narrow_1().unwrap(),
+						dot:(dot/(len*len) as i64).narrow_1().unwrap(),
 					};
 					let face_id=match face_id_from_face.get(&face){
 						Some(&face_id)=>face_id,
@@ -519,7 +519,8 @@ impl MeshQuery for TransformedMesh<'_>{
 		(transformed_n,transformed_d)
 	}
 	fn vert(&self,vert_id:SubmeshVertId)->Planar64Vec3{
-		self.transform.vertex.transform_point3(self.view.vert(vert_id)).fix_1()
+		// wrap for speed
+		self.transform.vertex.transform_point3(self.view.vert(vert_id)).wrap_1()
 	}
 	#[inline]
 	fn face_edges(&self,face_id:SubmeshFaceId)->impl AsRef<[SubmeshDirectedEdgeId]>{
@@ -659,7 +660,8 @@ impl MinkowskiMesh<'_>{
 				if !d.is_negative()&&d<=edge_nn{
 					let distance_squared={
 						let c=diff.cross(edge_n);
-						(c.dot(c)/edge_nn).divide().fix_2()
+						//wrap for speed
+						(c.dot(c)/edge_nn).divide().wrap_2()
 					};
 					if distance_squared<=*best_distance_squared{
 						best_transition=EV::Edge(directed_edge_id.as_undirected());
@@ -764,7 +766,7 @@ impl MinkowskiMesh<'_>{
 		};
 		let mut best_time={
 			let r=(time_limit-relative_body.time).to_ratio();
-			Ratio::new(r.num.fix_4(),r.den.fix_4())
+			Ratio::new(r.num.widen_4(),r.den.widen_4())
 		};
 		let mut best_edge=None;
 		let face_n=self.face_nd(contact_face_id).0;
@@ -776,7 +778,8 @@ impl MinkowskiMesh<'_>{
 			let d=n.dot(self.vert(v0)+self.vert(v1));
 			//WARNING! d outside of *2
 			//WARNING: truncated precision
-			for dt in Fixed::<4,128>::zeroes2(((n.dot(relative_body.position))*2-d).fix_4(),n.dot(relative_body.velocity).fix_4()*2,n.dot(relative_body.acceleration).fix_4()){
+			//wrap for speed
+			for dt in Fixed::<4,128>::zeroes2(((n.dot(relative_body.position))*2-d).wrap_4(),n.dot(relative_body.velocity).wrap_4()*2,n.dot(relative_body.acceleration).wrap_4()){
 				if start_time.le_ratio(dt)&&dt.lt_ratio(best_time)&&n.dot(relative_body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
 					best_time=dt;
 					best_edge=Some(directed_edge_id);
@@ -822,7 +825,7 @@ impl MeshQuery for MinkowskiMesh<'_>{
 				let n=edge0_n.cross(edge1_n);
 				let e0d=n.dot(self.mesh0.vert(e0v0)+self.mesh0.vert(e0v1));
 				let e1d=n.dot(self.mesh1.vert(e1v0)+self.mesh1.vert(e1v1));
-				((n*(parity as i64*4-2)).fix_3(),((e0d-e1d)*(parity as i64*2-1)).fix_4())
+				((n*(parity as i64*4-2)).widen_3(),((e0d-e1d)*(parity as i64*2-1)).widen_4())
 			},
 			MinkowskiFace::FaceVert(f0,v1)=>{
 				let (n,d)=self.mesh0.face_nd(f0);
@@ -954,7 +957,8 @@ impl MeshQuery for MinkowskiMesh<'_>{
 					face_normals.clone_from(&v0f_n);
 					for face_n in &v1f_n{
 						//add reflected mesh1 faces
-						face_normals.push(*face_n-(n*face_n.dot(n)*2/nn).divide().fix_3());
+						//wrap for speed
+						face_normals.push(*face_n-(n*face_n.dot(n)*2/nn).divide().wrap_3());
 					}
 					if is_empty_volume(face_normals){
 						edges.push(MinkowskiDirectedEdge::EdgeVert(directed_edge_id,v1));
@@ -966,7 +970,8 @@ impl MeshQuery for MinkowskiMesh<'_>{
 					let mut face_normals=Vec::with_capacity(the_len);
 					face_normals.clone_from(&v1f_n);
 					for face_n in &v0f_n{
-						face_normals.push(*face_n-(n*face_n.dot(n)*2/nn).divide().fix_3());
+						//wrap for speed
+						face_normals.push(*face_n-(n*face_n.dot(n)*2/nn).divide().wrap_3());
 					}
 					if is_empty_volume(face_normals){
 						edges.push(MinkowskiDirectedEdge::VertEdge(v0,directed_edge_id));
@@ -1008,6 +1013,6 @@ fn is_empty_volume(normals:Vec<Vector3<Fixed<3,96>>>)->bool{
 
 #[test]
 fn test_is_empty_volume(){
-	assert!(!is_empty_volume([vec3::X.fix_3(),vec3::Y.fix_3(),vec3::Z.fix_3()].to_vec()));
-	assert!(is_empty_volume([vec3::X.fix_3(),vec3::Y.fix_3(),vec3::Z.fix_3(),vec3::NEG_X.fix_3()].to_vec()));
+	assert!(!is_empty_volume([vec3::X.widen_3(),vec3::Y.widen_3(),vec3::Z.widen_3()].to_vec()));
+	assert!(is_empty_volume([vec3::X.widen_3(),vec3::Y.widen_3(),vec3::Z.widen_3(),vec3::NEG_X.widen_3()].to_vec()));
 }
diff --git a/engine/physics/src/physics.rs b/engine/physics/src/physics.rs
index 8644cb3ac..aaee9119c 100644
--- a/engine/physics/src/physics.rs
+++ b/engine/physics/src/physics.rs
@@ -117,8 +117,8 @@ impl TransientAcceleration{
 		}else{
 			//normal friction acceleration is clippedAcceleration.dot(normal)*friction
 			TransientAcceleration::Reachable{
-				acceleration:target_diff.with_length(accel).divide().fix_1(),
-				time:time+Time::from((target_diff.length()/accel).divide().fix_1())
+				acceleration:target_diff.with_length(accel).divide().wrap_1(),
+				time:time+Time::from((target_diff.length()/accel).divide().clamp_1())
 			}
 		}
 	}
@@ -407,7 +407,7 @@ impl HitboxMesh{
 		let transform=PhysicsMeshTransform::new(transform);
 		let transformed_mesh=TransformedMesh::new(mesh.complete_mesh_view(),&transform);
 		for vert in transformed_mesh.verts(){
-			aabb.grow(vert.fix_1());
+			aabb.grow(vert.narrow_1().unwrap());
 		}
 		Self{
 			halfsize:aabb.size()>>1,
@@ -460,12 +460,12 @@ impl StyleHelper for StyleModifiers{
 	}
 
 	fn get_y_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
-		(camera.rotation_y()*self.get_control_dir(controls)).fix_1()
+		(camera.rotation_y()*self.get_control_dir(controls)).wrap_1()
 	}
 
 	fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:Controls)->Planar64Vec3{
 		//don't interpolate this! discrete mouse movement, constant acceleration
-		(camera.rotation()*self.get_control_dir(controls)).fix_1()
+		(camera.rotation()*self.get_control_dir(controls)).wrap_1()
 	}
 	fn calculate_mesh(&self)->HitboxMesh{
 		let mesh=match self.hitbox.mesh{
@@ -1084,7 +1084,7 @@ impl PhysicsData{
 				let mut aabb=aabb::Aabb::default();
 				let transformed_mesh=TransformedMesh::new(view,transform);
 				for v in transformed_mesh.verts(){
-					aabb.grow(v.fix_1());
+					aabb.grow(v.narrow_1().unwrap());
 				}
 				(ConvexMeshId{
 					model_id,
@@ -1162,7 +1162,8 @@ fn contact_normal(models:&PhysicsModels,hitbox_mesh:&HitboxMesh,contact:&Contact
 	let model_mesh=models.contact_mesh(contact);
 	let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
 	// TODO: normalize to i64::MAX>>1
-	minkowski.face_nd(contact.face_id).0.fix_1()
+	// wrap for speed
+	minkowski.face_nd(contact.face_id).0.wrap_1()
 }
 
 fn recalculate_touching(
@@ -1321,7 +1322,7 @@ fn teleport_to_spawn(
 	const EPSILON:Planar64=Planar64::raw((1<<32)/16);
 	let transform=models.get_model_transform(spawn_model_id).ok_or(TeleportToSpawnError::NoModel)?;
 	//TODO: transform.vertex.matrix3.col(1)+transform.vertex.translation
-	let point=transform.vertex.transform_point3(vec3::Y).fix_1()+Planar64Vec3::new([Planar64::ZERO,style.hitbox.halfsize.y+EPSILON,Planar64::ZERO]);
+	let point=transform.vertex.transform_point3(vec3::Y).clamp_1()+Planar64Vec3::new([Planar64::ZERO,style.hitbox.halfsize.y+EPSILON,Planar64::ZERO]);
 	teleport(point,move_state,body,touching,run,mode_state,Some(mode),models,hitbox_mesh,bvh,style,camera,input_state,time);
 	Ok(())
 }
@@ -1485,7 +1486,7 @@ fn collision_start_contact(
 		Some(gameplay_attributes::ContactingBehaviour::Surf)=>(),
 		Some(gameplay_attributes::ContactingBehaviour::Cling)=>println!("Unimplemented!"),
 		&Some(gameplay_attributes::ContactingBehaviour::Elastic(elasticity))=>{
-			let reflected_velocity=body.velocity+((body.velocity-incident_velocity)*Planar64::raw(elasticity as i64+1)).fix_1();
+			let reflected_velocity=body.velocity+((body.velocity-incident_velocity)*Planar64::raw(elasticity as i64+1)).wrap_1();
 			set_velocity(body,touching,models,hitbox_mesh,reflected_velocity);
 		},
 		Some(gameplay_attributes::ContactingBehaviour::Ladder(contacting_ladder))=>
@@ -1708,7 +1709,7 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
 						let control_dir=state.style.get_control_dir(masked_controls);
 						if control_dir!=vec3::ZERO{
 							let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
-							if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE).divide().fix_1()){
+							if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE).divide().wrap_1()){
 								//this is wrong but will work ig
 								//need to note which push planes activate in push solve and keep those
 								state.cull_velocity(data,ticked_velocity);
diff --git a/engine/physics/src/push_solve.rs b/engine/physics/src/push_solve.rs
index 5b1c5a7e4..7432a19c3 100644
--- a/engine/physics/src/push_solve.rs
+++ b/engine/physics/src/push_solve.rs
@@ -152,18 +152,19 @@ const fn get_push_ray_0(point:Planar64Vec3)->Ray{
 	Ray{origin:point,direction:vec3::ZERO}
 }
 fn get_push_ray_1(point:Planar64Vec3,c0:&Contact)->Option<Ray>{
-	let direction=solve1(c0)?.divide().fix_1();
+	//wrap for speed
+	let direction=solve1(c0)?.divide().wrap_1();
 	let [s0]=decompose1(direction,c0.velocity)?;
 	if s0.lt_ratio(RATIO_ZERO){
 		return None;
 	}
 	let origin=point+solve1(
 		&c0.relative_to(point),
-	)?.divide().fix_1();
+	)?.divide().wrap_1();
 	Some(Ray{origin,direction})
 }
 fn get_push_ray_2(point:Planar64Vec3,c0:&Contact,c1:&Contact)->Option<Ray>{
-	let direction=solve2(c0,c1)?.divide().fix_1();
+	let direction=solve2(c0,c1)?.divide().wrap_1();
 	let [s0,s1]=decompose2(direction,c0.velocity,c1.velocity)?;
 	if s0.lt_ratio(RATIO_ZERO)||s1.lt_ratio(RATIO_ZERO){
 		return None;
@@ -171,11 +172,11 @@ fn get_push_ray_2(point:Planar64Vec3,c0:&Contact,c1:&Contact)->Option<Ray>{
 	let origin=point+solve2(
 		&c0.relative_to(point),
 		&c1.relative_to(point),
-	)?.divide().fix_1();
+	)?.divide().wrap_1();
 	Some(Ray{origin,direction})
 }
 fn get_push_ray_3(point:Planar64Vec3,c0:&Contact,c1:&Contact,c2:&Contact)->Option<Ray>{
-	let direction=solve3(c0,c1,c2)?.divide().fix_1();
+	let direction=solve3(c0,c1,c2)?.divide().wrap_1();
 	let [s0,s1,s2]=decompose3(direction,c0.velocity,c1.velocity,c2.velocity)?;
 	if s0.lt_ratio(RATIO_ZERO)||s1.lt_ratio(RATIO_ZERO)||s2.lt_ratio(RATIO_ZERO){
 		return None;
@@ -184,7 +185,7 @@ fn get_push_ray_3(point:Planar64Vec3,c0:&Contact,c1:&Contact,c2:&Contact)->Optio
 		&c0.relative_to(point),
 		&c1.relative_to(point),
 		&c2.relative_to(point),
-	)?.divide().fix_1();
+	)?.divide().wrap_1();
 	Some(Ray{origin,direction})
 }