diff --git a/strafe-client/src/physics.rs b/strafe-client/src/physics.rs
index 0180477..08145b2 100644
--- a/strafe-client/src/physics.rs
+++ b/strafe-client/src/physics.rs
@@ -1632,6 +1632,7 @@ fn collision_start_contact(
 	touching.insert(Collision::Contact(contact));
 	//clip v
 	set_velocity(body,touching,models,hitbox_mesh,incident_velocity);
+	let mut allow_jump=true;
 	let model_id=contact.model_id.into();
 	let mut allow_run_teleport_behaviour=not_spawn_at(mode,model_id);
 	match &attr.contacting.contact_behaviour{
@@ -1654,7 +1655,7 @@ fn collision_start_contact(
 			let walk_state=ContactMoveState::ladder(ladder_settings,body,gravity,target_velocity,contact);
 			move_state.set_move_state(MoveState::Ladder(walk_state),body,touching,models,hitbox_mesh,style,camera,input_state);
 		},
-		Some(gameplay_attributes::ContactingBehaviour::NoJump)=>todo!("nyi"),
+		Some(gameplay_attributes::ContactingBehaviour::NoJump)=>allow_jump=false,
 		None=>if let Some(walk_settings)=&style.walk{
 			if walk_settings.is_slope_walkable(contact_normal(models,hitbox_mesh,&contact),vec3::Y){
 				allow_run_teleport_behaviour=true;
@@ -1669,11 +1670,27 @@ fn collision_start_contact(
 	if allow_run_teleport_behaviour{
 		run_teleport_behaviour(model_id,attr.general.wormhole.as_ref(),mode,move_state,body,touching,run,mode_state,models,hitbox_mesh,bvh,style,camera,input_state,time);
 	}
-	if style.get_control(Controls::Jump,input_state.controls){
+	if allow_jump&&style.get_control(Controls::Jump,input_state.controls){
 		if let (Some(jump_settings),Some(walk_state))=(&style.jump,move_state.get_walk_state()){
-			let jump_dir=walk_state.jump_direction.direction(models,hitbox_mesh,&walk_state.contact);
-			let jumped_velocity=jump_settings.jumped_velocity(style,jump_dir,body.velocity,attr.general.booster.as_ref());
-			move_state.cull_velocity(jumped_velocity,body,touching,models,hitbox_mesh,style,camera,input_state);
+			let mut exceeded_jump_limit=false;
+			if let Some(mode)=mode{
+				if let Some(stage_element)=mode.get_element(model_id){
+					if !mode_state.try_increment_jump_count(model_id,stage_element.jump_limit()).is_allowed(){
+						exceeded_jump_limit=true;
+					}
+				}
+			}
+			if exceeded_jump_limit{
+				if let Some(mode)=mode{
+					if let Some(spawn_model_id)=mode.get_spawn_model_id(mode_state.get_stage_id()){
+						let _=teleport_to_spawn(spawn_model_id,move_state,body,touching,run,mode_state,mode,models,hitbox_mesh,bvh,style,camera,input_state,time);
+					}
+				}
+			}else{
+				let jump_dir=walk_state.jump_direction.direction(models,hitbox_mesh,&walk_state.contact);
+				let jumped_velocity=jump_settings.jumped_velocity(style,jump_dir,body.velocity,attr.general.booster.as_ref());
+				move_state.cull_velocity(jumped_velocity,body,touching,models,hitbox_mesh,style,camera,input_state);
+			}
 		}
 	}
 	match &attr.general.trajectory{