diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,8 +1,13 @@
 # Change Log
 
+## [0.0.2.2] - 2022-12-24
+
+- Fixed bits and flags in Data.Tiled.GID.
+- Added tile flag packing and unpacking into Word8/32.
+
 ## [0.0.2.1] - 2022-08-09
 
-- Fix `firstgid` field name in embedded tilesets.
+- Fixed `firstgid` field name in embedded tilesets.
 - Minimal `aeson` version is actually 2.0 (due to `KeyMap`).
 - `empty` values added for many «sparse» types.
 
diff --git a/aeson-tiled.cabal b/aeson-tiled.cabal
--- a/aeson-tiled.cabal
+++ b/aeson-tiled.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: aeson-tiled
-version: 0.0.2.1
+version: 0.0.2.2
 synopsis: Aeson instances for the Tiled map editor.
 description:
   The mighty Tiled 2D map editor is an open source
diff --git a/src/Data/Tiled/GID.hs b/src/Data/Tiled/GID.hs
--- a/src/Data/Tiled/GID.hs
+++ b/src/Data/Tiled/GID.hs
@@ -9,7 +9,7 @@
 import Data.Aeson (FromJSON(..), ToJSON(..))
 import Data.Bits (Bits(..), (.&.))
 import Data.Bool (bool)
-import Data.Word (Word32)
+import Data.Word (Word8, Word32)
 import Foreign (Storable(..))
 import GHC.Generics (Generic)
 
@@ -18,16 +18,16 @@
   deriving newtype (FromJSON, ToJSON, Storable, Bits)
 
 pattern FLIPPED_HORIZONTALLY_BIT :: Int
-pattern FLIPPED_HORIZONTALLY_BIT = 32
+pattern FLIPPED_HORIZONTALLY_BIT = 31
 
 pattern FLIPPED_VERTICALLY_BIT :: Int
-pattern FLIPPED_VERTICALLY_BIT = 31
+pattern FLIPPED_VERTICALLY_BIT = 30
 
 pattern ROTATED_60_BIT :: Int
-pattern ROTATED_60_BIT = 30
+pattern ROTATED_60_BIT = 29
 
 pattern ROTATED_120_BIT :: Int
-pattern ROTATED_120_BIT = 29
+pattern ROTATED_120_BIT = 28
 
 data Flags = Flags
   { flippedHorizontally :: Bool
@@ -36,14 +36,43 @@
   , rotated120          :: Bool
   } deriving (Eq, Show, Generic)
 
+{-# INLINEABLE flags #-}
 flags :: GID -> Flags
-flags (GID bits) = Flags
-  { flippedHorizontally = testBit bits FLIPPED_HORIZONTALLY_BIT
-  , flippedVertically   = testBit bits FLIPPED_VERTICALLY_BIT
-  , rotated60           = testBit bits ROTATED_60_BIT
-  , rotated120          = testBit bits ROTATED_120_BIT
+flags = unpack32 . getGID
+
+{-# INLINEABLE pack32 #-}
+pack32 :: Flags -> Word32
+pack32 Flags{..} =
+  bool 0 (bit FLIPPED_HORIZONTALLY_BIT) flippedHorizontally .|.
+  bool 0 (bit FLIPPED_VERTICALLY_BIT)   flippedVertically .|.
+  bool 0 (bit ROTATED_60_BIT)           rotated60 .|.
+  bool 0 (bit ROTATED_120_BIT)          rotated120
+
+{-# INLINEABLE unpack32 #-}
+unpack32 :: Word32 -> Flags
+unpack32 flags32 = Flags
+  { flippedHorizontally = testBit flags32 FLIPPED_HORIZONTALLY_BIT
+  , flippedVertically   = testBit flags32 FLIPPED_VERTICALLY_BIT
+  , rotated60           = testBit flags32 ROTATED_60_BIT
+  , rotated120          = testBit flags32 ROTATED_120_BIT
   }
 
+{-# INLINEABLE pack8 #-}
+pack8 :: Flags -> Word8
+pack8 flags = fromIntegral (pack32 flags `shiftR` 24)
+
+{-# INLINEABLE unpack8 #-}
+unpack8 :: Word8 -> Flags
+unpack8 bits8 = unpack32 (fromIntegral bits8 `shiftL` 24)
+
+noFlags :: Flags
+noFlags = Flags
+  { flippedHorizontally = False
+  , flippedVertically   = False
+  , rotated60           = False
+  , rotated120          = False
+  }
+
 flagBits :: Word32
 flagBits =
   bit FLIPPED_HORIZONTALLY_BIT .|.
@@ -55,10 +84,7 @@
 toLocal (GID bits) = fromIntegral $ bits .&. complement flagBits
 
 fromLocal :: Flags -> Int -> GID
-fromLocal Flags{..} localId =
-  GID . fromIntegral $
-    localId
-    .|. bool 0 FLIPPED_HORIZONTALLY_BIT flippedHorizontally
-    .|. bool 0 FLIPPED_VERTICALLY_BIT   flippedVertically
-    .|. bool 0 ROTATED_60_BIT           rotated60
-    .|. bool 0 ROTATED_120_BIT          rotated120
+fromLocal flags localId =
+  GID $
+    fromIntegral localId .|.
+    pack32 flags
