diff --git a/lib/common/src/physics.rs b/lib/common/src/physics.rs
index dc6be13..aa041ab 100644
--- a/lib/common/src/physics.rs
+++ b/lib/common/src/physics.rs
@@ -4,7 +4,6 @@ pub type Time=crate::integer::Time<TimeInner>;
 
 #[derive(Clone,Debug)]
 pub enum Instruction{
-	ReplaceMouse(crate::mouse::MouseState<TimeInner>,crate::mouse::MouseState<TimeInner>),
 	SetNextMouse(crate::mouse::MouseState<TimeInner>),
 	SetMoveRight(bool),
 	SetMoveUp(bool),
diff --git a/strafe-client/src/mouse_interpolator.rs b/strafe-client/src/mouse_interpolator.rs
index 5f5b8bc..420ba30 100644
--- a/strafe-client/src/mouse_interpolator.rs
+++ b/strafe-client/src/mouse_interpolator.rs
@@ -3,10 +3,11 @@ use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,Time as
 use strafesnet_common::session::{Time as SessionTime,TimeInner as SessionTimeInner};
 use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,TimedInstruction};
 
-use crate::session::StepInstruction as SessionInternalInstruction;
-
 type TimedPhysicsInstruction=TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>;
-type TimedInterpolatorInstruction=TimedInstruction<UnbufferedInputInstruction,SessionTimeInner>;
+type PhysicsTimedUnbufferedInstruction=TimedInstruction<UnbufferedInputInstruction,PhysicsTimeInner>;
+type DoubleTimedUnbufferedInstruction=TimedInstruction<PhysicsTimedUnbufferedInstruction,SessionTimeInner>;
+
+const MOUSE_TIMEOUT:SessionTime=SessionTime::from_millis(10);
 
 #[derive(Debug)]
 pub enum UnbufferedInputInstruction{
@@ -25,41 +26,84 @@ pub enum UnbufferedInputInstruction{
 	Idle,
 }
 
+pub enum StepInstruction{
+	Other,
+	ReplaceMouse,
+}
+
 pub struct MouseInterpolator{
+	last_mouse_state:MouseState<SessionTimeInner>,
+	// double timestamped timeline?
 	physics_timeline:std::collections::VecDeque<TimedPhysicsInstruction>,
 }
 // Maybe MouseInterpolator manipulation is better expressed using impls
 // and called from Instruction trait impls in session
-impl InstructionConsumer<UnbufferedInputInstruction> for MouseInterpolator{
+impl InstructionConsumer<PhysicsTimedUnbufferedInstruction> for MouseInterpolator{
 	type TimeInner=SessionTimeInner;
-	fn process_instruction(&mut self,ins:TimedInterpolatorInstruction){
+	fn process_instruction(&mut self,ins:DoubleTimedUnbufferedInstruction){
 		self.push_unbuffered_input(ins)
 	}
 }
-impl InstructionEmitter<SessionInternalInstruction> for MouseInterpolator{
+impl InstructionEmitter<StepInstruction> for MouseInterpolator{
 	type TimeInner=SessionTimeInner;
-	fn next_instruction(&self,time_limit:SessionTime)->Option<TimedInstruction<SessionInternalInstruction,Self::TimeInner>>{
+	fn next_instruction(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,Self::TimeInner>>{
 		self.buffered_instruction_with_timeout(time_limit)
 	}
 }
 impl MouseInterpolator{
 	pub fn new()->MouseInterpolator{
 		MouseInterpolator{
+			last_mouse_state:MouseState::default(),
 			physics_timeline:std::collections::VecDeque::new(),
 		}
 	}
-	pub fn push_unbuffered_input(&mut self,ins:TimedInterpolatorInstruction){
+	pub fn push_unbuffered_input(&mut self,ins:DoubleTimedUnbufferedInstruction){
 		// new input
+		// if there is zero instruction buffered, it means the mouse is not moving
 	}
-	pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option<TimedInstruction<SessionInternalInstruction,SessionTimeInner>>{
-		// if the mouse has stopped moving for over 10ms, emit DoStepReplaceMouse
-		// if there is a mouse interpolation target, emit DoStep
-		// else emit None
-		None
+	fn is_first_ready(&self)->bool{
+		// if the last instruction is a mouse instruction
+		// and there is 2 or more instructions
+		1<self.physics_timeline.len()&&matches!(self.physics_timeline.back(),Some(TimedInstruction{
+			instruction:PhysicsInputInstruction::SetNextMouse(_),
+			..
+		}))
 	}
-	pub fn pop_buffered_instruction(&mut self)->Option<TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>>{
-		// so the idea is that Session gets in the middle of MouseInterpolator instruction processing
-		// and injects its own side effects, notably running physics
+	pub fn buffered_instruction_with_timeout(&self,time_limit:SessionTime)->Option<TimedInstruction<StepInstruction,SessionTimeInner>>{
+		let timeout=self.last_mouse_state.time+MOUSE_TIMEOUT;
+		if timeout<time_limit{
+			// if the mouse has stopped moving for over 10ms, emit DoStepReplaceMouse at that exact timestamp
+			Some(TimedInstruction{
+				time:timeout,
+				instruction:StepInstruction::ReplaceMouse,
+			})
+		}else if self.is_first_ready(){
+			// emit Step
+			Some(TimedInstruction{
+				// this timestamp should not matter
+				// verify this and potentially emit a different type using the enum only
+				time:time_limit,
+				instruction:StepInstruction::Other,
+			})
+		}else{
+			None
+		}
+	}
+	pub fn pop_buffered_instruction(&mut self,ins:StepInstruction)->Option<TimedInstruction<PhysicsInputInstruction,PhysicsTimeInner>>{
+		match ins{
+			StepInstruction::Other=>{
+				// if the last instruction is a mouse instruction,
+				// then the buffer is in the process of flushing.
+				// pop and return the first event.
+				// if the first instruction is a mouse instruction,
+				// then events are being buffered to wait for another
+				// mouse instruction as an interpolation target
+			},
+			StepInstruction::ReplaceMouse=>{
+				// use the first instruction which should be a mouse instruction
+				// to push a ReplaceMouse instruction
+			},
+		}
 		None
 	}
 }
diff --git a/strafe-client/src/physics.rs b/strafe-client/src/physics.rs
index 16bbe48..f94fbe7 100644
--- a/strafe-client/src/physics.rs
+++ b/strafe-client/src/physics.rs
@@ -1759,7 +1759,6 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
 		|PhysicsInputInstruction::Idle=>false,
 		//these controls only update the body if you are on the ground
 		PhysicsInputInstruction::SetNextMouse(..)
-		|PhysicsInputInstruction::ReplaceMouse(..)
 		|PhysicsInputInstruction::SetMoveForward(..)
 		|PhysicsInputInstruction::SetMoveLeft(..)
 		|PhysicsInputInstruction::SetMoveBack(..)
@@ -1789,10 +1788,6 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
 						state.camera.move_mouse(state.input_state.mouse_delta());
 						state.input_state.set_next_mouse(m);
 					},
-					PhysicsInputInstruction::ReplaceMouse(m0,m1)=>{
-						state.camera.move_mouse(m0.pos-state.input_state.mouse.pos);
-						state.input_state.replace_mouse(m0,m1);
-					},
 					PhysicsInputInstruction::SetMoveForward(s)=>state.input_state.set_control(Controls::MoveForward,s),
 					PhysicsInputInstruction::SetMoveLeft(s)=>state.input_state.set_control(Controls::MoveLeft,s),
 					PhysicsInputInstruction::SetMoveBack(s)=>state.input_state.set_control(Controls::MoveBackward,s),
diff --git a/strafe-client/src/session.rs b/strafe-client/src/session.rs
index a4a1440..a015e81 100644
--- a/strafe-client/src/session.rs
+++ b/strafe-client/src/session.rs
@@ -5,7 +5,7 @@ use strafesnet_common::physics::{Instruction as PhysicsInputInstruction,TimeInne
 use strafesnet_common::timer::{Scaled,Timer};
 use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime};
 
-use crate::mouse_interpolator::{MouseInterpolator,UnbufferedInputInstruction};
+use crate::mouse_interpolator::{MouseInterpolator,UnbufferedInputInstruction,StepInstruction};
 
 pub enum ExternalInstruction{
 	ToBuffer(UnbufferedInputInstruction),
@@ -16,10 +16,6 @@ pub enum ExternalInstruction{
 	//Graphics(crate::graphics_worker::Instruction),
 }
 
-pub enum StepInstruction{
-	DoStep,
-}
-
 pub struct FrameState{
 	pub body:crate::physics::Body,
 	pub camera:crate::physics::PhysicsCamera,
@@ -92,10 +88,13 @@ impl InstructionConsumer<ExternalInstruction> for Session{
 	type TimeInner=SessionTimeInner;
 	fn process_instruction(&mut self,ins:TimedInstruction<ExternalInstruction,Self::TimeInner>){
 		match ins.instruction{
-			// send it down to MouseInterpolator
+			// send it down to MouseInterpolator with two timestamps, SessionTime and PhysicsTime
 			ExternalInstruction::ToBuffer(instruction)=>self.mouse_interpolator.process_instruction(TimedInstruction{
 				time:ins.time,
-				instruction,
+				instruction:TimedInstruction{
+					time:self.simulation.timer.time(ins.time),
+					instruction,
+				},
 			}),
 			ExternalInstruction::SetPaused(paused)=>{
 				// don't flush the buffered instructions in the mouse interpolator
@@ -114,12 +113,9 @@ impl InstructionConsumer<ExternalInstruction> for Session{
 impl InstructionConsumer<StepInstruction> for Session{
 	type TimeInner=SessionTimeInner;
 	fn process_instruction(&mut self,ins:TimedInstruction<StepInstruction,Self::TimeInner>){
-		match ins.instruction{
-			StepInstruction::DoStep=>{
-				if let Some(instruction)=self.mouse_interpolator.pop_buffered_instruction(){
-					self.simulation.physics.run_input_instruction(instruction);
-				}
-			}
+		// ins.time ignored???
+		if let Some(instruction)=self.mouse_interpolator.pop_buffered_instruction(ins.instruction){
+			self.simulation.physics.run_input_instruction(instruction);
 		}
 	}
 }