diff --git a/src/common.rs b/src/common.rs
index 09e1325..a5e017d 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -1,9 +1,15 @@
 use std::cmp::Ordering;
+use std::fmt;
 
+use ggez::GameError;
+use ggez::GameError::InvalidValue;
 use num_traits::{AsPrimitive, Num};
-use serde::{Deserialize, Serialize};
+use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
+use serde::de::{SeqAccess, Visitor};
+use serde::ser::SerializeTupleStruct;
 
 use crate::bitfield;
+use crate::macros::fmt::Formatter;
 
 /// Multiply cave story degrees (0-255, which corresponds to 0°-360°) with this to get
 /// respective value in radians.
@@ -217,7 +223,7 @@ impl Direction {
     }
 }
 
-#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
+#[derive(Debug, Clone, Copy)]
 pub struct Rect<T: Num + PartialOrd + Copy = isize> {
     pub left: T,
     pub top: T,
@@ -279,6 +285,63 @@ impl<T: Num + PartialOrd + Copy + AsPrimitive<f32>> Into<ggez::graphics::Rect> f
     }
 }
 
+impl<T: Num + PartialOrd + Copy + Serialize> Serialize for Rect<T> {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+    {
+        let mut state = serializer.serialize_tuple_struct("Rect", 4)?;
+        state.serialize_field(&self.left)?;
+        state.serialize_field(&self.top)?;
+        state.serialize_field(&self.right)?;
+        state.serialize_field(&self.bottom)?;
+        state.end()
+    }
+}
+macro_rules! rect_deserialze {
+    ($num_type: ident) => {
+        impl<'de> Deserialize<'de> for Rect<$num_type> {
+            fn deserialize<D>(deserializer: D) -> Result<Rect<$num_type>, D::Error>
+                where
+                    D: Deserializer<'de>,
+            {
+                struct RectVisitor;
+
+                impl<'de> Visitor<'de> for RectVisitor {
+                    type Value = Rect<$num_type>;
+
+                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                        formatter.write_str("Expected Rect structure.")
+                    }
+
+                    fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
+                        where
+                            V: SeqAccess<'de>
+                    {
+                        let invalid_length = || {
+                            de::Error::invalid_length(0, &self)
+                        };
+
+                        let left = seq.next_element()?.ok_or_else(invalid_length)?;
+                        let top = seq.next_element()?.ok_or_else(invalid_length)?;
+                        let right = seq.next_element()?.ok_or_else(invalid_length)?;
+                        let bottom = seq.next_element()?.ok_or_else(invalid_length)?;
+
+                        Ok(Rect { left, top, right, bottom })
+                    }
+                }
+
+                deserializer.deserialize_tuple_struct("Rect", 4, RectVisitor)
+            }
+        }
+    };
+}
+
+rect_deserialze!(u8);
+rect_deserialze!(u16);
+rect_deserialze!(isize);
+rect_deserialze!(usize);
+
 #[inline(always)]
 pub fn fix9_scale(val: isize, scale: f32) -> f32 {
     (val as f64 * scale as f64 / 512.0).floor() as f32 / scale