diff --git a/src/body.rs b/src/body.rs
index b60c221..7c60be9 100644
--- a/src/body.rs
+++ b/src/body.rs
@@ -5,6 +5,8 @@ pub enum PhysicsInstruction {
 	CollisionEnd(RelativeCollision),
 	StrafeTick,
 	Jump,
+	SetWalkTargetVelocity(glam::Vec3),
+	ReachWalkTargetVelocity,
 	// Water,
 	// Spawn(
 	// 	Option<SpawnId>,
@@ -19,6 +21,13 @@ pub struct Body {
 	pub time: TIME,//nanoseconds x xxxxD!
 }
 
+pub enum MoveRestriction {
+    Air,
+    Water,
+    Ground,
+    Ladder,//multiple ladders how
+}
+
 pub struct PhysicsState {
 	pub body: Body,
 	pub contacts: Vec<RelativeCollision>,
@@ -176,41 +185,19 @@ pub type TIME = i64;
 const CONTROL_JUMP:u32 = 0b01000000;//temp DATA NORMALIZATION!@#$
 impl PhysicsState {
 	//delete this, we are tickless gamers
-	pub fn run(&mut self, time: TIME, control_dir: glam::Vec3, controls: u32){
-		let target_tick = (time*self.strafe_tick_num/self.strafe_tick_den) as u32;
-		//the game code can run for 1 month before running out of ticks
-		while self.tick<target_tick {
-			self.tick += 1;
-			let dt=0.01;
-			let d=self.body.velocity.dot(control_dir);
-			if d<self.mv {
-				self.body.velocity+=(self.mv-d)*control_dir;
-			}
-			self.body.velocity+=self.gravity*dt;
-			self.body.position+=self.body.velocity*dt;
-			if self.body.position.y<0.0{
-				self.body.position.y=0.0;
-				self.body.velocity.y=0.0;
-				self.grounded=true;
-			}
-			if self.grounded&&(controls&CONTROL_JUMP)!=0 {
-				self.grounded=false;
-				self.body.velocity+=glam::Vec3::new(0.0,0.715588/2.0*100.0,0.0);
-			}
-			if self.grounded {
-				let applied_friction=self.friction*dt;
-				let targetv=control_dir*self.walkspeed;
-				let diffv=targetv-self.body.velocity;
-				if applied_friction*applied_friction<diffv.length_squared() {
-					self.body.velocity+=applied_friction*diffv.normalize();
-				} else {
-					//PhysicsInstruction::WalkTargetReached
-					self.body.velocity=targetv;
-				}
+	pub fn run(&mut self, time: TIME){
+		//prepare is ommitted - everything is done via instructions.
+		while let Some(instruction) = self.next_instruction() {//collect
+			if time<instruction.time {
+				break;
 			}
+			//advance
+			self.advance_time(instruction.time);
+			//process
+			self.process_instruction(instruction);
+			//write hash lol
 		}
 
-		self.body.time=target_tick as TIME*self.strafe_tick_den/self.strafe_tick_num;
 	}
 
 	//delete this
@@ -304,7 +291,31 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
 }
 
 impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
-	fn process_instruction(&mut self, instruction:TimedInstruction<PhysicsInstruction>) {
-		//
+	fn process_instruction(&mut self, ins:TimedInstruction<PhysicsInstruction>) {
+		//mutate position and velocity and time
+		self.body.advance_time(ins.time);//should this be in a separate function: self.advance_time?
+		match ins.instruction {
+		    PhysicsInstruction::CollisionStart(_) => todo!(),
+		    PhysicsInstruction::CollisionEnd(_) => todo!(),
+		    PhysicsInstruction::StrafeTick => {
+		    	let control_dir=self.get_control_dir();//this respects your mouse interpolation settings
+    			let d=self.body.velocity.dot(control_dir);
+    			if d<self.mv {
+    				self.body.velocity+=(self.mv-d)*control_dir;
+    			}
+    		}
+		    PhysicsInstruction::Jump => {
+				self.grounded=false;//do I need this?
+				self.body.velocity+=glam::Vec3::new(0.0,0.715588/2.0*100.0,0.0);
+			}
+		    PhysicsInstruction::ReachWalkTargetVelocity => {
+		    	//precisely set velocity
+				self.body.velocity=self.walk_target_velocity;
+			}
+    		PhysicsInstruction::SetWalkTargetVelocity(v) => {
+    			self.walk_target_velocity=v;
+    			//calculate acceleration yada yada
+    		},
+		}
 	}
 }
\ No newline at end of file