diff --git a/lib/common/src/timer.rs b/lib/common/src/timer.rs
index 59e558d..b75c68b 100644
--- a/lib/common/src/timer.rs
+++ b/lib/common/src/timer.rs
@@ -22,79 +22,106 @@ impl PauseState for Unpaused{
 	}
 }
 
+#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
+enum Inner{}
+type InnerTime=Time<Inner>;
+
 #[derive(Clone,Copy,Debug)]
-pub struct Realtime{
-	offset:Time,
+pub struct Realtime<In,Out>{
+	offset:InnerTime,
+	_in:core::marker::PhantomData<In>,
+	_out:core::marker::PhantomData<Out>,
 }
-impl Realtime{
-	pub const fn new(offset:Time)->Self{
-		Self{offset}
+impl<In,Out> Realtime<In,Out>{
+	pub const fn new(offset:InnerTime)->Self{
+		Self{
+			offset,
+			_in:core::marker::PhantomData,
+			_out:core::marker::PhantomData,
+		}
 	}
 }
 
 #[derive(Clone,Copy,Debug)]
-pub struct Scaled{
+pub struct Scaled<In,Out>{
 	scale:Ratio64,
-	offset:Time,
+	offset:InnerTime,
+	_in:core::marker::PhantomData<In>,
+	_out:core::marker::PhantomData<Out>,
 }
-impl Scaled{
-	pub const fn new(scale:Ratio64,offset:Time)->Self{
-		Self{scale,offset}
+impl<In,Out> Scaled<In,Out>
+	where Time<In>:Copy,
+{
+	pub const fn new(scale:Ratio64,offset:InnerTime)->Self{
+		Self{
+			scale,
+			offset,
+			_in:core::marker::PhantomData,
+			_out:core::marker::PhantomData,
+		}
 	}
 	const fn with_scale(scale:Ratio64)->Self{
-		Self{scale,offset:Time::ZERO}
+		Self::new(scale,InnerTime::ZERO)
 	}
-	const fn scale(&self,time:Time)->Time{
-		Time::raw(self.scale.mul_int(time.get()))
+	const fn scale(&self,time:Time<In>)->InnerTime{
+		InnerTime::raw(self.scale.mul_int(time.get()))
 	}
 	const fn get_scale(&self)->Ratio64{
 		self.scale
 	}
-	fn set_scale(&mut self,time:Time,new_scale:Ratio64){
+	fn set_scale(&mut self,time:Time<In>,new_scale:Ratio64){
 		let new_time=self.get_time(time);
 		self.scale=new_scale;
 		self.set_time(time,new_time);
 	}
 }
 
-pub trait TimerState:Copy+std::fmt::Debug{
+pub trait TimerState{
+	type In;
+	type Out;
 	fn identity()->Self;
-	fn get_time(&self,time:Time)->Time;
-	fn set_time(&mut self,time:Time,new_time:Time);
-	fn get_offset(&self)->Time;
-	fn set_offset(&mut self,offset:Time);
+	fn get_time(&self,time:Time<Self::In>)->Time<Self::Out>;
+	fn set_time(&mut self,time:Time<Self::In>,new_time:Time<Self::Out>);
+	fn get_offset(&self)->InnerTime;
+	fn set_offset(&mut self,offset:InnerTime);
 }
-impl TimerState for Realtime{
+impl<In,Out> TimerState for Realtime<In,Out>{
+	type In=In;
+	type Out=Out;
 	fn identity()->Self{
-		Self{offset:Time::ZERO}
+		Self::new(InnerTime::ZERO)
 	}
-	fn get_time(&self,time:Time)->Time{
-		time+self.offset
+	fn get_time(&self,time:Time<In>)->Time<Out>{
+		time.coerce()+self.offset.coerce()
 	}
-	fn set_time(&mut self,time:Time,new_time:Time){
-		self.offset=new_time-time;
+	fn set_time(&mut self,time:Time<In>,new_time:Time<Out>){
+		self.offset=new_time.coerce()-time.coerce();
 	}
-	fn get_offset(&self)->Time{
+	fn get_offset(&self)->InnerTime{
 		self.offset
 	}
-	fn set_offset(&mut self,offset:Time){
+	fn set_offset(&mut self,offset:InnerTime){
 		self.offset=offset;
 	}
 }
-impl TimerState for Scaled{
+impl<In,Out> TimerState for Scaled<In,Out>
+	where Time<In>:Copy,
+{
+	type In=In;
+	type Out=Out;
 	fn identity()->Self{
-		Self{scale:Ratio64::ONE,offset:Time::ZERO}
+		Self::new(Ratio64::ONE,InnerTime::ZERO)
 	}
-	fn get_time(&self,time:Time)->Time{
-		self.scale(time)+self.offset
+	fn get_time(&self,time:Time<In>)->Time<Out>{
+		(self.scale(time)+self.offset).coerce()
 	}
-	fn set_time(&mut self,time:Time,new_time:Time){
-		self.offset=new_time-self.scale(time);
+	fn set_time(&mut self,time:Time<In>,new_time:Time<Out>){
+		self.offset=new_time.coerce()-self.scale(time);
 	}
-	fn get_offset(&self)->Time{
+	fn get_offset(&self)->InnerTime{
 		self.offset
 	}
-	fn set_offset(&mut self,offset:Time){
+	fn set_offset(&mut self,offset:InnerTime){
 		self.offset=offset;
 	}
 }
@@ -106,8 +133,10 @@ pub struct TimerFixed<T:TimerState,P:PauseState>{
 }
 
 //scaled timer methods are generic across PauseState
-impl<P:PauseState> TimerFixed<Scaled,P>{
-	pub fn scaled(time:Time,new_time:Time,scale:Ratio64)->Self{
+impl<P:PauseState,In,Out> TimerFixed<Scaled<In,Out>,P>
+	where Time<In>:Copy,
+{
+	pub fn scaled(time:Time<In>,new_time:Time<Out>,scale:Ratio64)->Self{
 		let mut timer=Self{
 			state:Scaled::with_scale(scale),
 			_paused:P::new(),
@@ -118,14 +147,16 @@ impl<P:PauseState> TimerFixed<Scaled,P>{
 	pub const fn get_scale(&self)->Ratio64{
 		self.state.get_scale()
 	}
-	pub fn set_scale(&mut self,time:Time,new_scale:Ratio64){
+	pub fn set_scale(&mut self,time:Time<In>,new_scale:Ratio64){
 		self.state.set_scale(time,new_scale)
 	}
 }
 
 //pause and unpause is generic across TimerState
-impl<T:TimerState> TimerFixed<T,Paused>{
-	pub fn into_unpaused(self,time:Time)->TimerFixed<T,Unpaused>{
+impl<T:TimerState> TimerFixed<T,Paused>
+	where Time<T::In>:Copy,
+{
+	pub fn into_unpaused(self,time:Time<T::In>)->TimerFixed<T,Unpaused>{
 		let new_time=self.time(time);
 		let mut timer=TimerFixed{
 			state:self.state,
@@ -135,8 +166,10 @@ impl<T:TimerState> TimerFixed<T,Paused>{
 		timer
 	}
 }
-impl<T:TimerState> TimerFixed<T,Unpaused>{
-	pub fn into_paused(self,time:Time)->TimerFixed<T,Paused>{
+impl<T:TimerState> TimerFixed<T,Unpaused>
+	where Time<T::In>:Copy,
+{
+	pub fn into_paused(self,time:Time<T::In>)->TimerFixed<T,Paused>{
 		let new_time=self.time(time);
 		let mut timer=TimerFixed{
 			state:self.state,
@@ -149,7 +182,7 @@ impl<T:TimerState> TimerFixed<T,Unpaused>{
 
 //the new constructor and time queries are generic across both
 impl<T:TimerState,P:PauseState> TimerFixed<T,P>{
-	pub fn new(time:Time,new_time:Time)->Self{
+	pub fn new(time:Time<T::In>,new_time:Time<T::Out>)->Self{
 		let mut timer=Self{
 			state:T::identity(),
 			_paused:P::new(),
@@ -166,15 +199,15 @@ impl<T:TimerState,P:PauseState> TimerFixed<T,P>{
 	pub fn into_state(self)->T{
 		self.state
 	}
-	pub fn time(&self,time:Time)->Time{
+	pub fn time(&self,time:Time<T::In>)->Time<T::Out>{
 		match P::IS_PAUSED{
-			true=>self.state.get_offset(),
+			true=>self.state.get_offset().coerce(),
 			false=>self.state.get_time(time),
 		}
 	}
-	pub fn set_time(&mut self,time:Time,new_time:Time){
+	pub fn set_time(&mut self,time:Time<T::In>,new_time:Time<T::Out>){
 		match P::IS_PAUSED{
-			true=>self.state.set_offset(new_time),
+			true=>self.state.set_offset(new_time.coerce()),
 			false=>self.state.set_time(time,new_time),
 		}
 	}
@@ -198,7 +231,11 @@ pub enum Timer<T:TimerState>{
 	Paused(TimerFixed<T,Paused>),
 	Unpaused(TimerFixed<T,Unpaused>),
 }
-impl<T:TimerState> Timer<T>{
+impl<T:TimerState> Timer<T>
+	where
+		T:Copy,
+		Time<T::In>:Copy,
+{
 	pub fn from_state(state:T,paused:bool)->Self{
 		match paused{
 			true=>Self::Paused(TimerFixed::from_state(state)),
@@ -211,32 +248,32 @@ impl<T:TimerState> Timer<T>{
 			Self::Unpaused(timer)=>(timer.into_state(),false),
 		}
 	}
-	pub fn paused(time:Time,new_time:Time)->Self{
+	pub fn paused(time:Time<T::In>,new_time:Time<T::Out>)->Self{
 		Self::Paused(TimerFixed::new(time,new_time))
 	}
-	pub fn unpaused(time:Time,new_time:Time)->Self{
+	pub fn unpaused(time:Time<T::In>,new_time:Time<T::Out>)->Self{
 		Self::Unpaused(TimerFixed::new(time,new_time))
 	}
-	pub fn time(&self,time:Time)->Time{
+	pub fn time(&self,time:Time<T::In>)->Time<T::Out>{
 		match self{
 			Self::Paused(timer)=>timer.time(time),
 			Self::Unpaused(timer)=>timer.time(time),
 		}
 	}
-	pub fn set_time(&mut self,time:Time,new_time:Time){
+	pub fn set_time(&mut self,time:Time<T::In>,new_time:Time<T::Out>){
 		match self{
 			Self::Paused(timer)=>timer.set_time(time,new_time),
 			Self::Unpaused(timer)=>timer.set_time(time,new_time),
 		}
 	}
-	pub fn pause(&mut self,time:Time)->Result<(),Error>{
+	pub fn pause(&mut self,time:Time<T::In>)->Result<(),Error>{
 		*self=match *self{
 			Self::Paused(_)=>return Err(Error::AlreadyPaused),
 			Self::Unpaused(timer)=>Self::Paused(timer.into_paused(time)),
 		};
 		Ok(())
 	}
-	pub fn unpause(&mut self,time:Time)->Result<(),Error>{
+	pub fn unpause(&mut self,time:Time<T::In>)->Result<(),Error>{
 		*self=match *self{
 			Self::Paused(timer)=>Self::Unpaused(timer.into_unpaused(time)),
 			Self::Unpaused(_)=>return Err(Error::AlreadyUnpaused),
@@ -249,7 +286,7 @@ impl<T:TimerState> Timer<T>{
 			Self::Unpaused(_)=>false,
 		}
 	}
-	pub fn set_paused(&mut self,time:Time,paused:bool)->Result<(),Error>{
+	pub fn set_paused(&mut self,time:Time<T::In>,paused:bool)->Result<(),Error>{
 		match paused{
 			true=>self.pause(time),
 			false=>self.unpause(time),
@@ -257,14 +294,16 @@ impl<T:TimerState> Timer<T>{
 	}
 }
 //scaled timer methods are generic across PauseState
-impl Timer<Scaled>{
+impl<In,Out> Timer<Scaled<In,Out>>
+	where Time<In>:Copy,
+{
 	pub const fn get_scale(&self)->Ratio64{
 		match self{
 			Self::Paused(timer)=>timer.get_scale(),
 			Self::Unpaused(timer)=>timer.get_scale(),
 		}
 	}
-	pub fn set_scale(&mut self,time:Time,new_scale:Ratio64){
+	pub fn set_scale(&mut self,time:Time<In>,new_scale:Ratio64){
 		match self{
 			Self::Paused(timer)=>timer.set_scale(time,new_scale),
 			Self::Unpaused(timer)=>timer.set_scale(time,new_scale),
@@ -280,10 +319,15 @@ mod test{
 			Time::from_secs($s)
 		};
 	}
+
+	#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
+	enum Parent{}
+	#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
+	enum Calculated{}
 	#[test]
 	fn test_timerfixed_scaled(){
 		//create a paused timer that reads 0s
-		let timer=TimerFixed::<Scaled,Paused>::from_state(Scaled{scale:0.5f32.try_into().unwrap(),offset:sec!(0)});
+		let timer=TimerFixed::<Scaled<Parent,Calculated>,Paused>::from_state(Scaled::new(0.5f32.try_into().unwrap(),sec!(0)));
 		//the paused timer at 1 second should read 0s
 		assert_eq!(timer.time(sec!(1)),sec!(0));
 
@@ -300,7 +344,7 @@ mod test{
 	#[test]
 	fn test_timer()->Result<(),Error>{
 		//create a paused timer that reads 0s
-		let mut timer=Timer::<Realtime>::paused(sec!(0),sec!(0));
+		let mut timer=Timer::<Realtime<Parent,Calculated>>::paused(sec!(0),sec!(0));
 		//the paused timer at 1 second should read 0s
 		assert_eq!(timer.time(sec!(1)),sec!(0));