diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -3,9 +3,25 @@
 [![Version badge][]][version]
 [![Windows build badge][]][windows build]
 [![Build badge][]][build]
+[![Docker build badge][]][docker build]
 
-Rattletrap parses and generates [Rocket League][] replays.
+Rattletrap parses and generates [Rocket League][] replays. Parsing replays can
+be used to analyze data in order to collect high-level statistics like players
+and points, or low-level details like positions and cameras. Generating replays
+can be used to modify replays in order to force everyone into the same car or
+change the map a game was played on.
 
+Rattletrap supports every version of Rocket League up to [1.62][], also known
+as the "esports shop update". If a replay can be played by the Rocket League
+client, it can be parsed by Rattletrap. (If not, that's a bug. Please report
+it!)
+
+Rattletrap is a command-line application. You should only use it if you're
+comfortable running things in terminals or command prompts. Otherwise consider
+using another tool like [Ball Chasing][]. Rattletrap is written in [Haskell][].
+If you'd like to use a program written in a different language, consider
+@jjbott's [C# parser][] or @nickbabcock's [Rust parser][].
+
 ## Install
 
 Get Rattletrap by downloading and unpacking [the latest release][] for your
@@ -35,13 +51,14 @@
 
 ``` sh
 > rattletrap --help
-rattletrap version 4.0.0
-  -c             --compact                minify JSON output
-  -h             --help                   show the help
-  -i FILE|URL    --input=FILE|URL         input file or URL
-  -m MODE        --mode=MODE              decode or encode
-  -o FILE        --output=FILE            output file
-  -v             --version                show the version
+rattletrap.EXE version 6.4.0
+  -c           --compact         minify JSON output
+  -f           --fast            only encode or decode the header
+  -h           --help            show the help
+  -i FILE|URL  --input=FILE|URL  input file or URL
+  -m MODE      --mode=MODE       decode or encode
+  -o FILE      --output=FILE     output file
+  -v           --version         show the version
 ```
 
 By default Rattletrap will try to determine the appropriate mode (either decode
@@ -64,7 +81,7 @@
 ``` sh
 > rattletrap --input http://example.com/input.replay --output output.json
 # or
-> rattletrap -i input.replay > output.json
+> rattletrap -i input.replay -o output.json
 # or
 > rattletrap < input.replay > output.json
 ```
@@ -76,6 +93,10 @@
 output can be up to 100 times larger than the input. For example, a 1.5 MB
 replay turns into 31 MB of minified JSON or 159 MB of pretty-printed JSON.
 
+Be aware that Rattletrap can output some very large numbers! Some languages,
+like JavaScript, don't natively support parsing them from JSON. See issue #117
+for details.
+
 ## Generate
 
 Rattletrap can also generate (encode) Rocket League replays from JSON files.
@@ -83,7 +104,7 @@
 ``` sh
 > rattletrap --input http://example.com/input.json --output output.replay
 # or
-> rattletrap -i input.json > output.replay
+> rattletrap -i input.json -o output.replay
 # or
 > rattletrap --mode encode < input.json > output.replay
 ```
@@ -105,12 +126,19 @@
 ```
 
 [Rattletrap]: https://github.com/tfausak/rattletrap
-[Version badge]: https://img.shields.io/hackage/v/rattletrap.svg?label=version
+[Version badge]: https://img.shields.io/hackage/v/rattletrap.svg?logo=haskell&label=version&color=brightgreen
 [version]: https://hackage.haskell.org/package/rattletrap
-[Windows build badge]: https://img.shields.io/appveyor/ci/taylorfausak/rattletrap/master.svg?logo=appveyor
+[Windows build badge]: https://img.shields.io/appveyor/ci/taylorfausak/rattletrap/master.svg?logo=appveyor&logoColor=white
 [windows build]: https://ci.appveyor.com/project/taylorfausak/rattletrap
-[Build badge]: https://img.shields.io/travis/tfausak/rattletrap/master.svg
+[Build badge]: https://img.shields.io/travis/tfausak/rattletrap/master.svg?logo=travis-ci&logoColor=white
 [build]: https://travis-ci.org/tfausak/rattletrap
-[Rocket League]: https://www.rocketleaguegame.com
+[Docker build badge]: https://img.shields.io/docker/build/taylorfausak/rattletrap.svg?label=docker&logo=docker&logoColor=white
+[docker build]: https://hub.docker.com/r/taylorfausak/rattletrap
+[Rocket League]: https://www.rocketleague.com
+[1.62]: https://www.rocketleague.com/news/patch-notes-v1-62/
+[Ball Chasing]: https://ballchasing.com
+[Haskell]: https://www.haskell.org
+[C# parser]: https://github.com/jjbott/RocketLeagueReplayParser
+[Rust parser]: https://github.com/nickbabcock/rrrocket
 [the latest release]: https://github.com/tfausak/rattletrap/releases/latest
 [Stack]: https://docs.haskellstack.org/en/stable/README/
diff --git a/executables/Main.hs b/executables/Main.hs
--- a/executables/Main.hs
+++ b/executables/Main.hs
@@ -3,4 +3,4 @@
   )
 where
 
-import Rattletrap.Console.Main (main)
+import Rattletrap (main)
diff --git a/library/Rattletrap.hs b/library/Rattletrap.hs
--- a/library/Rattletrap.hs
+++ b/library/Rattletrap.hs
@@ -1,85 +1,101 @@
 module Rattletrap
-  ( Rattletrap.Utility.Helper.decodeReplayFile
+  ( Rattletrap.Console.Main.main
+  , Rattletrap.Console.Main.rattletrap
+  , Rattletrap.Utility.Helper.decodeReplayFile
   , Rattletrap.Utility.Helper.encodeReplayJson
   , Rattletrap.Utility.Helper.decodeReplayJson
   , Rattletrap.Utility.Helper.encodeReplayFile
-  , Rattletrap.Type.Replay.Replay(..)
-  , Rattletrap.Type.Section.Section(..)
-  , Rattletrap.Type.Header.Header(..)
-  , Rattletrap.Type.Word32le.Word32le(..)
-  , Rattletrap.Type.Str.Str(..)
-  , Rattletrap.Type.Dictionary.Dictionary(..)
-  , Rattletrap.Type.Property.Property(..)
-  , Rattletrap.Type.Word64le.Word64le(..)
-  , Rattletrap.Type.PropertyValue.PropertyValue(..)
-  , Rattletrap.Type.List.List(..)
-  , Rattletrap.Type.Word8le.Word8le(..)
-  , Rattletrap.Type.Float32le.Float32le(..)
-  , Rattletrap.Type.Int32le.Int32le(..)
-  , Rattletrap.Type.Content.Content(..)
-  , Rattletrap.Type.KeyFrame.KeyFrame(..)
-  , Rattletrap.Type.Frame.Frame(..)
-  , Rattletrap.Type.Replication.Replication(..)
-  , Rattletrap.Type.CompressedWord.CompressedWord(..)
-  , Rattletrap.Type.ReplicationValue.ReplicationValue(..)
-  , Rattletrap.Type.SpawnedReplication.SpawnedReplication(..)
-  , Rattletrap.Type.Initialization.Initialization(..)
-  , Rattletrap.Type.Vector.Vector(..)
-  , Rattletrap.Type.Int8Vector.Int8Vector(..)
-  , Rattletrap.Type.Int8le.Int8le(..)
-  , Rattletrap.Type.UpdatedReplication.UpdatedReplication(..)
+  , Rattletrap.Type.AppliedDamageAttribute.AppliedDamageAttribute(..)
   , Rattletrap.Type.Attribute.Attribute(..)
+  , Rattletrap.Type.AttributeMapping.AttributeMapping(..)
+  , Rattletrap.Type.AttributeType.AttributeType(..)
   , Rattletrap.Type.AttributeValue.AttributeValue(..)
-  , Rattletrap.Type.AppliedDamageAttribute.AppliedDamageAttribute(..)
+  , Rattletrap.Type.Bitstream.Bitstream(..)
   , Rattletrap.Type.BooleanAttribute.BooleanAttribute(..)
   , Rattletrap.Type.ByteAttribute.ByteAttribute(..)
+  , Rattletrap.Type.Cache.Cache(..)
   , Rattletrap.Type.CamSettingsAttribute.CamSettingsAttribute(..)
+  , Rattletrap.Type.ClassAttributeMap.ClassAttributeMap(..)
+  , Rattletrap.Type.ClassMapping.ClassMapping(..)
   , Rattletrap.Type.ClubColorsAttribute.ClubColorsAttribute(..)
+  , Rattletrap.Type.CompressedWord.CompressedWord(..)
+  , Rattletrap.Type.CompressedWordVector.CompressedWordVector(..)
+  , Rattletrap.Type.Content.Content(..)
   , Rattletrap.Type.DamageStateAttribute.DamageStateAttribute(..)
   , Rattletrap.Type.DemolishAttribute.DemolishAttribute(..)
+  , Rattletrap.Type.DestroyedReplication.DestroyedReplication(..)
+  , Rattletrap.Type.Dictionary.Dictionary(..)
   , Rattletrap.Type.EnumAttribute.EnumAttribute(..)
   , Rattletrap.Type.ExplosionAttribute.ExplosionAttribute(..)
   , Rattletrap.Type.ExtendedExplosionAttribute.ExtendedExplosionAttribute(..)
   , Rattletrap.Type.FlaggedIntAttribute.FlaggedIntAttribute(..)
+  , Rattletrap.Type.Float32le.Float32le(..)
   , Rattletrap.Type.FloatAttribute.FloatAttribute(..)
+  , Rattletrap.Type.Frame.Frame(..)
   , Rattletrap.Type.GameModeAttribute.GameModeAttribute(..)
+  , Rattletrap.Type.Header.Header(..)
+  , Rattletrap.Type.Initialization.Initialization(..)
+  , Rattletrap.Type.Int32le.Int32le(..)
+  , Rattletrap.Type.Int64Attribute.Int64Attribute(..)
+  , Rattletrap.Type.Int64le.Int64le(..)
+  , Rattletrap.Type.Int8le.Int8le(..)
+  , Rattletrap.Type.Int8Vector.Int8Vector(..)
   , Rattletrap.Type.IntAttribute.IntAttribute(..)
+  , Rattletrap.Type.KeyFrame.KeyFrame(..)
+  , Rattletrap.Type.List.List(..)
   , Rattletrap.Type.LoadoutAttribute.LoadoutAttribute(..)
   , Rattletrap.Type.LoadoutOnlineAttribute.LoadoutOnlineAttribute(..)
-  , Rattletrap.Type.ProductAttribute.ProductAttribute(..)
   , Rattletrap.Type.LoadoutsAttribute.LoadoutsAttribute(..)
   , Rattletrap.Type.LoadoutsOnlineAttribute.LoadoutsOnlineAttribute(..)
   , Rattletrap.Type.LocationAttribute.LocationAttribute(..)
+  , Rattletrap.Type.Mark.Mark(..)
+  , Rattletrap.Type.Message.Message(..)
   , Rattletrap.Type.MusicStingerAttribute.MusicStingerAttribute(..)
   , Rattletrap.Type.PartyLeaderAttribute.PartyLeaderAttribute(..)
-  , Rattletrap.Type.RemoteId.RemoteId(..)
   , Rattletrap.Type.PickupAttribute.PickupAttribute(..)
+  , Rattletrap.Type.PlayerHistoryKeyAttribute.PlayerHistoryKeyAttribute(..)
   , Rattletrap.Type.PrivateMatchSettingsAttribute.PrivateMatchSettingsAttribute(..)
+  , Rattletrap.Type.ProductAttribute.ProductAttribute(..)
+  , Rattletrap.Type.Property.Property(..)
+  , Rattletrap.Type.PropertyValue.PropertyValue(..)
+  , Rattletrap.Type.Quaternion.Quaternion(..)
   , Rattletrap.Type.QWordAttribute.QWordAttribute(..)
+  , Rattletrap.Type.RemoteId.RemoteId(..)
+  , Rattletrap.Type.Replay.Replay(..)
+  , Rattletrap.Type.Replication.Replication(..)
+  , Rattletrap.Type.ReplicationValue.ReplicationValue(..)
   , Rattletrap.Type.ReservationAttribute.ReservationAttribute(..)
-  , Rattletrap.Type.UniqueIdAttribute.UniqueIdAttribute(..)
   , Rattletrap.Type.RigidBodyStateAttribute.RigidBodyStateAttribute(..)
-  , Rattletrap.Type.CompressedWordVector.CompressedWordVector(..)
+  , Rattletrap.Type.Rotation.Rotation(..)
+  , Rattletrap.Type.Section.Section(..)
+  , Rattletrap.Type.SpawnedReplication.SpawnedReplication(..)
+  , Rattletrap.Type.StatEventAttribute.StatEventAttribute(..)
+  , Rattletrap.Type.Str.Str(..)
   , Rattletrap.Type.StringAttribute.StringAttribute(..)
   , Rattletrap.Type.TeamPaintAttribute.TeamPaintAttribute(..)
+  , Rattletrap.Type.TitleAttribute.TitleAttribute(..)
+  , Rattletrap.Type.UniqueIdAttribute.UniqueIdAttribute(..)
+  , Rattletrap.Type.UpdatedReplication.UpdatedReplication(..)
+  , Rattletrap.Type.Vector.Vector(..)
   , Rattletrap.Type.WeldedInfoAttribute.WeldedInfoAttribute(..)
-  , Rattletrap.Type.DestroyedReplication.DestroyedReplication(..)
-  , Rattletrap.Type.Message.Message(..)
-  , Rattletrap.Type.Mark.Mark(..)
-  , Rattletrap.Type.ClassMapping.ClassMapping(..)
-  , Rattletrap.Type.Cache.Cache(..)
-  , Rattletrap.Type.AttributeMapping.AttributeMapping(..)
+  , Rattletrap.Type.Word32le.Word32le(..)
+  , Rattletrap.Type.Word64le.Word64le(..)
+  , Rattletrap.Type.Word8le.Word8le(..)
   )
 where
 
+import qualified Rattletrap.Console.Main
 import qualified Rattletrap.Type.AppliedDamageAttribute
 import qualified Rattletrap.Type.Attribute
 import qualified Rattletrap.Type.AttributeMapping
+import qualified Rattletrap.Type.AttributeType
 import qualified Rattletrap.Type.AttributeValue
+import qualified Rattletrap.Type.Bitstream
 import qualified Rattletrap.Type.BooleanAttribute
 import qualified Rattletrap.Type.ByteAttribute
 import qualified Rattletrap.Type.Cache
 import qualified Rattletrap.Type.CamSettingsAttribute
+import qualified Rattletrap.Type.ClassAttributeMap
 import qualified Rattletrap.Type.ClassMapping
 import qualified Rattletrap.Type.ClubColorsAttribute
 import qualified Rattletrap.Type.CompressedWord
@@ -100,8 +116,10 @@
 import qualified Rattletrap.Type.Header
 import qualified Rattletrap.Type.Initialization
 import qualified Rattletrap.Type.Int32le
-import qualified Rattletrap.Type.Int8Vector
+import qualified Rattletrap.Type.Int64Attribute
+import qualified Rattletrap.Type.Int64le
 import qualified Rattletrap.Type.Int8le
+import qualified Rattletrap.Type.Int8Vector
 import qualified Rattletrap.Type.IntAttribute
 import qualified Rattletrap.Type.KeyFrame
 import qualified Rattletrap.Type.List
@@ -115,10 +133,12 @@
 import qualified Rattletrap.Type.MusicStingerAttribute
 import qualified Rattletrap.Type.PartyLeaderAttribute
 import qualified Rattletrap.Type.PickupAttribute
+import qualified Rattletrap.Type.PlayerHistoryKeyAttribute
 import qualified Rattletrap.Type.PrivateMatchSettingsAttribute
 import qualified Rattletrap.Type.ProductAttribute
 import qualified Rattletrap.Type.Property
 import qualified Rattletrap.Type.PropertyValue
+import qualified Rattletrap.Type.Quaternion
 import qualified Rattletrap.Type.QWordAttribute
 import qualified Rattletrap.Type.RemoteId
 import qualified Rattletrap.Type.Replay
@@ -126,11 +146,14 @@
 import qualified Rattletrap.Type.ReplicationValue
 import qualified Rattletrap.Type.ReservationAttribute
 import qualified Rattletrap.Type.RigidBodyStateAttribute
+import qualified Rattletrap.Type.Rotation
 import qualified Rattletrap.Type.Section
 import qualified Rattletrap.Type.SpawnedReplication
+import qualified Rattletrap.Type.StatEventAttribute
 import qualified Rattletrap.Type.Str
 import qualified Rattletrap.Type.StringAttribute
 import qualified Rattletrap.Type.TeamPaintAttribute
+import qualified Rattletrap.Type.TitleAttribute
 import qualified Rattletrap.Type.UniqueIdAttribute
 import qualified Rattletrap.Type.UpdatedReplication
 import qualified Rattletrap.Type.Vector
diff --git a/library/Rattletrap/Console/Main.hs b/library/Rattletrap/Console/Main.hs
--- a/library/Rattletrap/Console/Main.hs
+++ b/library/Rattletrap/Console/Main.hs
@@ -12,7 +12,8 @@
 import qualified Network.HTTP.Client as Client
 import qualified Network.HTTP.Client.TLS as Client
 import qualified Paths_rattletrap as This
-import qualified Rattletrap
+import qualified Rattletrap.Type.Replay as Rattletrap
+import qualified Rattletrap.Utility.Helper as Rattletrap
 import qualified System.Console.GetOpt as Console
 import qualified System.Environment as Environment
 import qualified System.Exit as Exit
diff --git a/library/Rattletrap/Decode/Attribute.hs b/library/Rattletrap/Decode/Attribute.hs
--- a/library/Rattletrap/Decode/Attribute.hs
+++ b/library/Rattletrap/Decode/Attribute.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Decode.Attribute
   ( decodeAttributesBits
-  , decodeAttributeBits
   )
 where
 
diff --git a/library/Rattletrap/Decode/Frame.hs b/library/Rattletrap/Decode/Frame.hs
--- a/library/Rattletrap/Decode/Frame.hs
+++ b/library/Rattletrap/Decode/Frame.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Decode.Frame
   ( decodeFramesBits
-  , decodeFrameBits
   )
 where
 
diff --git a/library/Rattletrap/Decode/Int64le.hs b/library/Rattletrap/Decode/Int64le.hs
--- a/library/Rattletrap/Decode/Int64le.hs
+++ b/library/Rattletrap/Decode/Int64le.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Decode.Int64le
-  ( decodeInt64le
-  , decodeInt64leBits
+  ( decodeInt64leBits
   )
 where
 
diff --git a/library/Rattletrap/Decode/Int8le.hs b/library/Rattletrap/Decode/Int8le.hs
--- a/library/Rattletrap/Decode/Int8le.hs
+++ b/library/Rattletrap/Decode/Int8le.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Decode.Int8le
-  ( decodeInt8le
-  , decodeInt8leBits
+  ( decodeInt8leBits
   )
 where
 
diff --git a/library/Rattletrap/Decode/ProductAttribute.hs b/library/Rattletrap/Decode/ProductAttribute.hs
--- a/library/Rattletrap/Decode/ProductAttribute.hs
+++ b/library/Rattletrap/Decode/ProductAttribute.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Decode.ProductAttribute
   ( decodeProductAttributesBits
-  , decodeProductAttributeBits
   )
 where
 
diff --git a/library/Rattletrap/Decode/Replication.hs b/library/Rattletrap/Decode/Replication.hs
--- a/library/Rattletrap/Decode/Replication.hs
+++ b/library/Rattletrap/Decode/Replication.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Decode.Replication
   ( decodeReplicationsBits
-  , decodeReplicationBits
   )
 where
 
diff --git a/library/Rattletrap/Encode/Attribute.hs b/library/Rattletrap/Encode/Attribute.hs
--- a/library/Rattletrap/Encode/Attribute.hs
+++ b/library/Rattletrap/Encode/Attribute.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Encode.Attribute
   ( putAttributes
-  , putAttribute
   )
 where
 
diff --git a/library/Rattletrap/Encode/Frame.hs b/library/Rattletrap/Encode/Frame.hs
--- a/library/Rattletrap/Encode/Frame.hs
+++ b/library/Rattletrap/Encode/Frame.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Encode.Frame
   ( putFrames
-  , putFrame
   )
 where
 
diff --git a/library/Rattletrap/Encode/Int64le.hs b/library/Rattletrap/Encode/Int64le.hs
--- a/library/Rattletrap/Encode/Int64le.hs
+++ b/library/Rattletrap/Encode/Int64le.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Encode.Int64le
-  ( putInt64
-  , putInt64Bits
+  ( putInt64Bits
   )
 where
 
diff --git a/library/Rattletrap/Encode/Int8le.hs b/library/Rattletrap/Encode/Int8le.hs
--- a/library/Rattletrap/Encode/Int8le.hs
+++ b/library/Rattletrap/Encode/Int8le.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Encode.Int8le
-  ( putInt8
-  , putInt8Bits
+  ( putInt8Bits
   )
 where
 
diff --git a/library/Rattletrap/Encode/ProductAttribute.hs b/library/Rattletrap/Encode/ProductAttribute.hs
--- a/library/Rattletrap/Encode/ProductAttribute.hs
+++ b/library/Rattletrap/Encode/ProductAttribute.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Encode.ProductAttribute
   ( putProductAttributes
-  , putProductAttribute
   )
 where
 
diff --git a/library/Rattletrap/Encode/Replication.hs b/library/Rattletrap/Encode/Replication.hs
--- a/library/Rattletrap/Encode/Replication.hs
+++ b/library/Rattletrap/Encode/Replication.hs
@@ -1,6 +1,5 @@
 module Rattletrap.Encode.Replication
   ( putReplications
-  , putReplication
   )
 where
 
diff --git a/library/Rattletrap/Type/CompressedWord.hs b/library/Rattletrap/Type/CompressedWord.hs
--- a/library/Rattletrap/Type/CompressedWord.hs
+++ b/library/Rattletrap/Type/CompressedWord.hs
@@ -7,6 +7,8 @@
 
 import Rattletrap.Type.Common
 
+-- | Although there's no guarantee that these values will not overflow, it's
+-- exceptionally unlikely. Most 'CompressedWord's are very small.
 data CompressedWord = CompressedWord
   { compressedWordLimit :: Word
   , compressedWordValue :: Word
diff --git a/library/Rattletrap/Type/GameModeAttribute.hs b/library/Rattletrap/Type/GameModeAttribute.hs
--- a/library/Rattletrap/Type/GameModeAttribute.hs
+++ b/library/Rattletrap/Type/GameModeAttribute.hs
@@ -9,6 +9,10 @@
 
 data GameModeAttribute = GameModeAttribute
   { gameModeAttributeNumBits :: Int
+  -- ^ This field is guaranteed to be small. In other words, it won't overflow.
+  -- It's stored as a regular 'Int' rather than something more precise like an
+  -- 'Int8' because it just gets passed to functions that expect 'Int's.
+  -- There's no reason to do a bunch of conversions.
   , gameModeAttributeWord :: Word8
   } deriving (Eq, Ord, Show)
 
diff --git a/library/Rattletrap/Type/Int64le.hs b/library/Rattletrap/Type/Int64le.hs
--- a/library/Rattletrap/Type/Int64le.hs
+++ b/library/Rattletrap/Type/Int64le.hs
@@ -1,14 +1,28 @@
-{-# LANGUAGE TemplateHaskell #-}
-
 module Rattletrap.Type.Int64le
   ( Int64le(..)
   )
 where
 
-import Rattletrap.Type.Common
+import qualified Data.Aeson as Aeson
+import qualified Data.Aeson.Types as Aeson
+import qualified Data.Int as Int
+import qualified Data.Scientific as Scientific
+import qualified Data.Text as Text
+import qualified Text.Read as Read
 
 newtype Int64le = Int64le
-  { int64leValue :: Int64
+  { int64leValue :: Int.Int64
   } deriving (Eq, Ord, Show)
 
-$(deriveJson ''Int64le)
+instance Aeson.FromJSON Int64le where
+  parseJSON value = case value of
+    Aeson.String text -> case Read.readEither $ Text.unpack text of
+      Left _ -> Aeson.typeMismatch "Int64le" value
+      Right int64 -> pure $ Int64le int64
+    Aeson.Number number -> case Scientific.toBoundedInteger number of
+      Nothing -> Aeson.typeMismatch "Int64le" value
+      Just int64 -> pure $ Int64le int64
+    _ -> Aeson.typeMismatch "Int64le" value
+
+instance Aeson.ToJSON Int64le where
+  toJSON = Aeson.toJSON . show . int64leValue
diff --git a/library/Rattletrap/Type/Quaternion.hs b/library/Rattletrap/Type/Quaternion.hs
--- a/library/Rattletrap/Type/Quaternion.hs
+++ b/library/Rattletrap/Type/Quaternion.hs
@@ -4,7 +4,6 @@
   ( Quaternion(..)
   , Component(..)
   , toQuaternion
-  , toPart
   , compressPart
   , decompressPart
   , maxComponent
diff --git a/library/Rattletrap/Type/Vector.hs b/library/Rattletrap/Type/Vector.hs
--- a/library/Rattletrap/Type/Vector.hs
+++ b/library/Rattletrap/Type/Vector.hs
@@ -11,9 +11,16 @@
 data Vector = Vector
   { vectorSize :: CompressedWord
   , vectorBias :: Word
+  -- ^ This field is guaranteed to be small. In other words, it won't overflow.
+  -- It's stored as a regular 'Word' rather than something more precise like a
+  -- 'Word8' because it just gets passed to a functions that expect 'Word's.
+  -- There's no reason to do a bunch of conversions.
   , vectorX :: Int
+  -- ^ See 'vectorBias'.
   , vectorY :: Int
+  -- ^ See 'vectorBias'.
   , vectorZ :: Int
+  -- ^ See 'vectorBias'.
   } deriving (Eq, Ord, Show)
 
 $(deriveJson ''Vector)
diff --git a/library/Rattletrap/Type/Word64le.hs b/library/Rattletrap/Type/Word64le.hs
--- a/library/Rattletrap/Type/Word64le.hs
+++ b/library/Rattletrap/Type/Word64le.hs
@@ -1,14 +1,28 @@
-{-# LANGUAGE TemplateHaskell #-}
-
 module Rattletrap.Type.Word64le
   ( Word64le(..)
   )
 where
 
-import Rattletrap.Type.Common
+import qualified Data.Aeson as Aeson
+import qualified Data.Aeson.Types as Aeson
+import qualified Data.Scientific as Scientific
+import qualified Data.Text as Text
+import qualified Data.Word as Word
+import qualified Text.Read as Read
 
 newtype Word64le = Word64le
-  { word64leValue :: Word64
+  { word64leValue :: Word.Word64
   } deriving (Eq, Ord, Show)
 
-$(deriveJson ''Word64le)
+instance Aeson.FromJSON Word64le where
+  parseJSON value = case value of
+    Aeson.String text -> case Read.readEither $ Text.unpack text of
+      Left _ -> Aeson.typeMismatch "Word64le" value
+      Right word64 -> pure $ Word64le word64
+    Aeson.Number number -> case Scientific.toBoundedInteger number of
+      Nothing -> Aeson.typeMismatch "Word64le" value
+      Just word64 -> pure $ Word64le word64
+    _ -> Aeson.typeMismatch "Word64le" value
+
+instance Aeson.ToJSON Word64le where
+  toJSON = Aeson.toJSON . show . word64leValue
diff --git a/library/Rattletrap/Utility/Bytes.hs b/library/Rattletrap/Utility/Bytes.hs
--- a/library/Rattletrap/Utility/Bytes.hs
+++ b/library/Rattletrap/Utility/Bytes.hs
@@ -1,7 +1,6 @@
 module Rattletrap.Utility.Bytes
   ( encodeLatin1
   , padBytes
-  , reverseByte
   , reverseBytes
   )
 where
diff --git a/package.yaml b/package.yaml
deleted file mode 100644
--- a/package.yaml
+++ /dev/null
@@ -1,70 +0,0 @@
-name: rattletrap
-version: 6.4.0
-
-category: Game
-description: Rattletrap parses and generates Rocket League replays.
-extra-source-files:
-  - CHANGELOG.markdown
-  - package.yaml
-  - README.markdown
-  - stack.yaml
-github: tfausak/rattletrap
-license-file: LICENSE.markdown
-license: MIT
-maintainer: Taylor Fausak
-synopsis: Parse and generate Rocket League replays.
-
-dependencies:
-  aeson-pretty: '>= 0.8.5 && < 0.9'
-  aeson: '>= 1.2.4 && < 1.5'
-  base: '>= 4.11.1 && < 4.13'
-  binary-bits: '>= 0.5 && < 0.6'
-  binary: '>= 0.8.5 && < 0.9'
-  bytestring: '>= 0.10.8 && < 0.11'
-  containers: '>= 0.5.10 && < 0.7'
-  filepath: '>= 1.4.1 && < 1.5'
-  http-client-tls: '>= 0.3.5 && < 0.4'
-  http-client: '>= 0.5.10 && < 0.7'
-  template-haskell: '>= 2.13.0 && < 2.15'
-  text: '>= 1.2.3 && < 1.3'
-  transformers: '>= 0.5.2 && < 0.6'
-ghc-options:
-  - -optP -Wno-nonportable-include-path # https://github.com/haskell/cabal/issues/4739
-  - -Weverything
-  - -Wno-all-missed-specialisations
-  - -Wno-implicit-prelude
-  - -Wno-missing-exported-signatures # https://ghc.haskell.org/trac/ghc/ticket/14794
-  - -Wno-missing-import-lists
-  - -Wno-safe
-  - -Wno-unsafe
-
-flags:
-  static:
-    default: false
-    manual: true
-
-library:
-  source-dirs: library
-
-executable:
-  dependencies: rattletrap
-  ghc-options:
-    - -rtsopts
-    - -threaded
-  main: Main.hs
-  source-dirs: executables
-  when:
-    - condition: flag(static)
-      ld-options: -static
-
-tests:
-  test:
-    dependencies:
-      HUnit: '>= 1.6.0 && < 1.7'
-      rattletrap: -any
-      temporary: '>= 1.2.1 && < 1.4'
-    ghc-options:
-      - -rtsopts
-      - -threaded
-    main: Main.hs
-    source-dirs: tests
diff --git a/rattletrap.cabal b/rattletrap.cabal
--- a/rattletrap.cabal
+++ b/rattletrap.cabal
@@ -1,27 +1,15 @@
-cabal-version: 1.12
+cabal-version: 2.4
 
--- This file has been generated from package.yaml by hpack version 0.31.0.
---
--- see: https://github.com/sol/hpack
---
--- hash: 63f9e1d505db6c0f8a8dc124bd223add14a91d41451c9f8d86a0b5b6e21ece6a
+name: rattletrap
+version: 7.0.0
 
-name:           rattletrap
-version:        6.4.0
-synopsis:       Parse and generate Rocket League replays.
-description:    Rattletrap parses and generates Rocket League replays.
-category:       Game
-homepage:       https://github.com/tfausak/rattletrap#readme
-bug-reports:    https://github.com/tfausak/rattletrap/issues
-maintainer:     Taylor Fausak
-license:        MIT
-license-file:   LICENSE.markdown
-build-type:     Simple
-extra-source-files:
-    CHANGELOG.markdown
-    package.yaml
-    README.markdown
-    stack.yaml
+category: Game
+description: Rattletrap parses and generates Rocket League replays.
+extra-source-files: CHANGELOG.markdown README.markdown stack.yaml
+license-file: LICENSE.markdown
+license: MIT
+maintainer: Taylor Fausak
+synopsis: Parse and generate Rocket League replays.
 
 source-repository head
   type: git
@@ -31,310 +19,291 @@
   manual: True
   default: False
 
-library
-  exposed-modules:
-      Rattletrap
-      Rattletrap.Console.Main
-      Rattletrap.Data
-      Rattletrap.Decode.AppliedDamageAttribute
-      Rattletrap.Decode.Attribute
-      Rattletrap.Decode.AttributeMapping
-      Rattletrap.Decode.AttributeValue
-      Rattletrap.Decode.Bitstream
-      Rattletrap.Decode.BooleanAttribute
-      Rattletrap.Decode.ByteAttribute
-      Rattletrap.Decode.Cache
-      Rattletrap.Decode.CamSettingsAttribute
-      Rattletrap.Decode.ClassMapping
-      Rattletrap.Decode.ClubColorsAttribute
-      Rattletrap.Decode.Common
-      Rattletrap.Decode.CompressedWord
-      Rattletrap.Decode.CompressedWordVector
-      Rattletrap.Decode.Content
-      Rattletrap.Decode.DamageStateAttribute
-      Rattletrap.Decode.DemolishAttribute
-      Rattletrap.Decode.DestroyedReplication
-      Rattletrap.Decode.Dictionary
-      Rattletrap.Decode.EnumAttribute
-      Rattletrap.Decode.ExplosionAttribute
-      Rattletrap.Decode.ExtendedExplosionAttribute
-      Rattletrap.Decode.FlaggedIntAttribute
-      Rattletrap.Decode.Float32le
-      Rattletrap.Decode.FloatAttribute
-      Rattletrap.Decode.Frame
-      Rattletrap.Decode.GameModeAttribute
-      Rattletrap.Decode.Header
-      Rattletrap.Decode.Initialization
-      Rattletrap.Decode.Int32le
-      Rattletrap.Decode.Int64Attribute
-      Rattletrap.Decode.Int64le
-      Rattletrap.Decode.Int8le
-      Rattletrap.Decode.Int8Vector
-      Rattletrap.Decode.IntAttribute
-      Rattletrap.Decode.KeyFrame
-      Rattletrap.Decode.List
-      Rattletrap.Decode.LoadoutAttribute
-      Rattletrap.Decode.LoadoutOnlineAttribute
-      Rattletrap.Decode.LoadoutsAttribute
-      Rattletrap.Decode.LoadoutsOnlineAttribute
-      Rattletrap.Decode.LocationAttribute
-      Rattletrap.Decode.Mark
-      Rattletrap.Decode.Message
-      Rattletrap.Decode.MusicStingerAttribute
-      Rattletrap.Decode.PartyLeaderAttribute
-      Rattletrap.Decode.PickupAttribute
-      Rattletrap.Decode.PlayerHistoryKeyAttribute
-      Rattletrap.Decode.PrivateMatchSettingsAttribute
-      Rattletrap.Decode.ProductAttribute
-      Rattletrap.Decode.Property
-      Rattletrap.Decode.PropertyValue
-      Rattletrap.Decode.Quaternion
-      Rattletrap.Decode.QWordAttribute
-      Rattletrap.Decode.RemoteId
-      Rattletrap.Decode.Replay
-      Rattletrap.Decode.Replication
-      Rattletrap.Decode.ReplicationValue
-      Rattletrap.Decode.ReservationAttribute
-      Rattletrap.Decode.RigidBodyStateAttribute
-      Rattletrap.Decode.Rotation
-      Rattletrap.Decode.Section
-      Rattletrap.Decode.SpawnedReplication
-      Rattletrap.Decode.StatEventAttribute
-      Rattletrap.Decode.Str
-      Rattletrap.Decode.StringAttribute
-      Rattletrap.Decode.TeamPaintAttribute
-      Rattletrap.Decode.TitleAttribute
-      Rattletrap.Decode.UniqueIdAttribute
-      Rattletrap.Decode.UpdatedReplication
-      Rattletrap.Decode.Vector
-      Rattletrap.Decode.WeldedInfoAttribute
-      Rattletrap.Decode.Word32le
-      Rattletrap.Decode.Word64le
-      Rattletrap.Decode.Word8le
-      Rattletrap.Encode.AppliedDamageAttribute
-      Rattletrap.Encode.Attribute
-      Rattletrap.Encode.AttributeMapping
-      Rattletrap.Encode.AttributeValue
-      Rattletrap.Encode.Bitstream
-      Rattletrap.Encode.BooleanAttribute
-      Rattletrap.Encode.ByteAttribute
-      Rattletrap.Encode.Cache
-      Rattletrap.Encode.CamSettingsAttribute
-      Rattletrap.Encode.ClassMapping
-      Rattletrap.Encode.ClubColorsAttribute
-      Rattletrap.Encode.CompressedWord
-      Rattletrap.Encode.CompressedWordVector
-      Rattletrap.Encode.Content
-      Rattletrap.Encode.DamageStateAttribute
-      Rattletrap.Encode.DemolishAttribute
-      Rattletrap.Encode.DestroyedReplication
-      Rattletrap.Encode.Dictionary
-      Rattletrap.Encode.EnumAttribute
-      Rattletrap.Encode.ExplosionAttribute
-      Rattletrap.Encode.ExtendedExplosionAttribute
-      Rattletrap.Encode.FlaggedIntAttribute
-      Rattletrap.Encode.Float32le
-      Rattletrap.Encode.FloatAttribute
-      Rattletrap.Encode.Frame
-      Rattletrap.Encode.GameModeAttribute
-      Rattletrap.Encode.Header
-      Rattletrap.Encode.Initialization
-      Rattletrap.Encode.Int32le
-      Rattletrap.Encode.Int64Attribute
-      Rattletrap.Encode.Int64le
-      Rattletrap.Encode.Int8le
-      Rattletrap.Encode.Int8Vector
-      Rattletrap.Encode.IntAttribute
-      Rattletrap.Encode.KeyFrame
-      Rattletrap.Encode.List
-      Rattletrap.Encode.LoadoutAttribute
-      Rattletrap.Encode.LoadoutOnlineAttribute
-      Rattletrap.Encode.LoadoutsAttribute
-      Rattletrap.Encode.LoadoutsOnlineAttribute
-      Rattletrap.Encode.LocationAttribute
-      Rattletrap.Encode.Mark
-      Rattletrap.Encode.Message
-      Rattletrap.Encode.MusicStingerAttribute
-      Rattletrap.Encode.PartyLeaderAttribute
-      Rattletrap.Encode.PickupAttribute
-      Rattletrap.Encode.PlayerHistoryKeyAttribute
-      Rattletrap.Encode.PrivateMatchSettingsAttribute
-      Rattletrap.Encode.ProductAttribute
-      Rattletrap.Encode.Property
-      Rattletrap.Encode.PropertyValue
-      Rattletrap.Encode.Quaternion
-      Rattletrap.Encode.QWordAttribute
-      Rattletrap.Encode.RemoteId
-      Rattletrap.Encode.Replay
-      Rattletrap.Encode.Replication
-      Rattletrap.Encode.ReplicationValue
-      Rattletrap.Encode.ReservationAttribute
-      Rattletrap.Encode.RigidBodyStateAttribute
-      Rattletrap.Encode.Rotation
-      Rattletrap.Encode.Section
-      Rattletrap.Encode.SpawnedReplication
-      Rattletrap.Encode.StatEventAttribute
-      Rattletrap.Encode.Str
-      Rattletrap.Encode.StringAttribute
-      Rattletrap.Encode.TeamPaintAttribute
-      Rattletrap.Encode.TitleAttribute
-      Rattletrap.Encode.UniqueIdAttribute
-      Rattletrap.Encode.UpdatedReplication
-      Rattletrap.Encode.Vector
-      Rattletrap.Encode.WeldedInfoAttribute
-      Rattletrap.Encode.Word32le
-      Rattletrap.Encode.Word64le
-      Rattletrap.Encode.Word8le
-      Rattletrap.Type.AppliedDamageAttribute
-      Rattletrap.Type.Attribute
-      Rattletrap.Type.AttributeMapping
-      Rattletrap.Type.AttributeType
-      Rattletrap.Type.AttributeValue
-      Rattletrap.Type.Bitstream
-      Rattletrap.Type.BooleanAttribute
-      Rattletrap.Type.ByteAttribute
-      Rattletrap.Type.Cache
-      Rattletrap.Type.CamSettingsAttribute
-      Rattletrap.Type.ClassAttributeMap
-      Rattletrap.Type.ClassMapping
-      Rattletrap.Type.ClubColorsAttribute
-      Rattletrap.Type.Common
-      Rattletrap.Type.CompressedWord
-      Rattletrap.Type.CompressedWordVector
-      Rattletrap.Type.Content
-      Rattletrap.Type.DamageStateAttribute
-      Rattletrap.Type.DemolishAttribute
-      Rattletrap.Type.DestroyedReplication
-      Rattletrap.Type.Dictionary
-      Rattletrap.Type.EnumAttribute
-      Rattletrap.Type.ExplosionAttribute
-      Rattletrap.Type.ExtendedExplosionAttribute
-      Rattletrap.Type.FlaggedIntAttribute
-      Rattletrap.Type.Float32le
-      Rattletrap.Type.FloatAttribute
-      Rattletrap.Type.Frame
-      Rattletrap.Type.GameModeAttribute
-      Rattletrap.Type.Header
-      Rattletrap.Type.Initialization
-      Rattletrap.Type.Int32le
-      Rattletrap.Type.Int64Attribute
-      Rattletrap.Type.Int64le
-      Rattletrap.Type.Int8le
-      Rattletrap.Type.Int8Vector
-      Rattletrap.Type.IntAttribute
-      Rattletrap.Type.KeyFrame
-      Rattletrap.Type.List
-      Rattletrap.Type.LoadoutAttribute
-      Rattletrap.Type.LoadoutOnlineAttribute
-      Rattletrap.Type.LoadoutsAttribute
-      Rattletrap.Type.LoadoutsOnlineAttribute
-      Rattletrap.Type.LocationAttribute
-      Rattletrap.Type.Mark
-      Rattletrap.Type.Message
-      Rattletrap.Type.MusicStingerAttribute
-      Rattletrap.Type.PartyLeaderAttribute
-      Rattletrap.Type.PickupAttribute
-      Rattletrap.Type.PlayerHistoryKeyAttribute
-      Rattletrap.Type.PrivateMatchSettingsAttribute
-      Rattletrap.Type.ProductAttribute
-      Rattletrap.Type.Property
-      Rattletrap.Type.PropertyValue
-      Rattletrap.Type.Quaternion
-      Rattletrap.Type.QWordAttribute
-      Rattletrap.Type.RemoteId
-      Rattletrap.Type.Replay
-      Rattletrap.Type.Replication
-      Rattletrap.Type.ReplicationValue
-      Rattletrap.Type.ReservationAttribute
-      Rattletrap.Type.RigidBodyStateAttribute
-      Rattletrap.Type.Rotation
-      Rattletrap.Type.Section
-      Rattletrap.Type.SpawnedReplication
-      Rattletrap.Type.StatEventAttribute
-      Rattletrap.Type.Str
-      Rattletrap.Type.StringAttribute
-      Rattletrap.Type.TeamPaintAttribute
-      Rattletrap.Type.TitleAttribute
-      Rattletrap.Type.UniqueIdAttribute
-      Rattletrap.Type.UpdatedReplication
-      Rattletrap.Type.Vector
-      Rattletrap.Type.WeldedInfoAttribute
-      Rattletrap.Type.Word32le
-      Rattletrap.Type.Word64le
-      Rattletrap.Type.Word8le
-      Rattletrap.Utility.Bytes
-      Rattletrap.Utility.Crc
-      Rattletrap.Utility.Helper
-  other-modules:
-      Paths_rattletrap
-  hs-source-dirs:
-      library
-  ghc-options: -optP -Wno-nonportable-include-path -Weverything -Wno-all-missed-specialisations -Wno-implicit-prelude -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-safe -Wno-unsafe
+common basics
   build-depends:
-      aeson >=1.2.4 && <1.5
-    , aeson-pretty >=0.8.5 && <0.9
-    , base >=4.11.1 && <4.13
-    , binary >=0.8.5 && <0.9
-    , binary-bits >=0.5 && <0.6
-    , bytestring >=0.10.8 && <0.11
-    , containers >=0.5.10 && <0.7
-    , filepath >=1.4.1 && <1.5
-    , http-client >=0.5.10 && <0.7
-    , http-client-tls >=0.3.5 && <0.4
-    , template-haskell >=2.13.0 && <2.15
-    , text >=1.2.3 && <1.3
-    , transformers >=0.5.2 && <0.6
+    aeson ^>= 1.4.2,
+    aeson-pretty ^>= 0.8.7,
+    base ^>= 4.12.0,
+    binary ^>= 0.8.6,
+    binary-bits ^>= 0.5,
+    bytestring ^>= 0.10.8,
+    containers ^>= 0.6.0,
+    filepath ^>= 1.4.2,
+    http-client ^>= 0.5.14,
+    http-client-tls ^>= 0.3.5,
+    scientific ^>= 0.3.6,
+    template-haskell ^>= 2.14.0,
+    text ^>= 1.2.3,
+    transformers ^>= 0.5.6,
   default-language: Haskell2010
+  ghc-options:
+    -optP -Wno-nonportable-include-path
+    -Weverything
+    -Wno-all-missed-specialisations
+    -Wno-implicit-prelude
+    -Wno-missing-exported-signatures
+    -Wno-missing-import-lists
+    -Wno-safe
+    -Wno-unsafe
 
+library
+  import: basics
+
+  autogen-modules: Paths_rattletrap
+  exposed-modules: Rattletrap
+  hs-source-dirs: library
+  other-modules:
+    Paths_rattletrap
+    Rattletrap.Console.Main
+    Rattletrap.Data
+    Rattletrap.Decode.AppliedDamageAttribute
+    Rattletrap.Decode.Attribute
+    Rattletrap.Decode.AttributeMapping
+    Rattletrap.Decode.AttributeValue
+    Rattletrap.Decode.Bitstream
+    Rattletrap.Decode.BooleanAttribute
+    Rattletrap.Decode.ByteAttribute
+    Rattletrap.Decode.Cache
+    Rattletrap.Decode.CamSettingsAttribute
+    Rattletrap.Decode.ClassMapping
+    Rattletrap.Decode.ClubColorsAttribute
+    Rattletrap.Decode.Common
+    Rattletrap.Decode.CompressedWord
+    Rattletrap.Decode.CompressedWordVector
+    Rattletrap.Decode.Content
+    Rattletrap.Decode.DamageStateAttribute
+    Rattletrap.Decode.DemolishAttribute
+    Rattletrap.Decode.DestroyedReplication
+    Rattletrap.Decode.Dictionary
+    Rattletrap.Decode.EnumAttribute
+    Rattletrap.Decode.ExplosionAttribute
+    Rattletrap.Decode.ExtendedExplosionAttribute
+    Rattletrap.Decode.FlaggedIntAttribute
+    Rattletrap.Decode.Float32le
+    Rattletrap.Decode.FloatAttribute
+    Rattletrap.Decode.Frame
+    Rattletrap.Decode.GameModeAttribute
+    Rattletrap.Decode.Header
+    Rattletrap.Decode.Initialization
+    Rattletrap.Decode.Int32le
+    Rattletrap.Decode.Int64Attribute
+    Rattletrap.Decode.Int64le
+    Rattletrap.Decode.Int8le
+    Rattletrap.Decode.Int8Vector
+    Rattletrap.Decode.IntAttribute
+    Rattletrap.Decode.KeyFrame
+    Rattletrap.Decode.List
+    Rattletrap.Decode.LoadoutAttribute
+    Rattletrap.Decode.LoadoutOnlineAttribute
+    Rattletrap.Decode.LoadoutsAttribute
+    Rattletrap.Decode.LoadoutsOnlineAttribute
+    Rattletrap.Decode.LocationAttribute
+    Rattletrap.Decode.Mark
+    Rattletrap.Decode.Message
+    Rattletrap.Decode.MusicStingerAttribute
+    Rattletrap.Decode.PartyLeaderAttribute
+    Rattletrap.Decode.PickupAttribute
+    Rattletrap.Decode.PlayerHistoryKeyAttribute
+    Rattletrap.Decode.PrivateMatchSettingsAttribute
+    Rattletrap.Decode.ProductAttribute
+    Rattletrap.Decode.Property
+    Rattletrap.Decode.PropertyValue
+    Rattletrap.Decode.Quaternion
+    Rattletrap.Decode.QWordAttribute
+    Rattletrap.Decode.RemoteId
+    Rattletrap.Decode.Replay
+    Rattletrap.Decode.Replication
+    Rattletrap.Decode.ReplicationValue
+    Rattletrap.Decode.ReservationAttribute
+    Rattletrap.Decode.RigidBodyStateAttribute
+    Rattletrap.Decode.Rotation
+    Rattletrap.Decode.Section
+    Rattletrap.Decode.SpawnedReplication
+    Rattletrap.Decode.StatEventAttribute
+    Rattletrap.Decode.Str
+    Rattletrap.Decode.StringAttribute
+    Rattletrap.Decode.TeamPaintAttribute
+    Rattletrap.Decode.TitleAttribute
+    Rattletrap.Decode.UniqueIdAttribute
+    Rattletrap.Decode.UpdatedReplication
+    Rattletrap.Decode.Vector
+    Rattletrap.Decode.WeldedInfoAttribute
+    Rattletrap.Decode.Word32le
+    Rattletrap.Decode.Word64le
+    Rattletrap.Decode.Word8le
+    Rattletrap.Encode.AppliedDamageAttribute
+    Rattletrap.Encode.Attribute
+    Rattletrap.Encode.AttributeMapping
+    Rattletrap.Encode.AttributeValue
+    Rattletrap.Encode.Bitstream
+    Rattletrap.Encode.BooleanAttribute
+    Rattletrap.Encode.ByteAttribute
+    Rattletrap.Encode.Cache
+    Rattletrap.Encode.CamSettingsAttribute
+    Rattletrap.Encode.ClassMapping
+    Rattletrap.Encode.ClubColorsAttribute
+    Rattletrap.Encode.CompressedWord
+    Rattletrap.Encode.CompressedWordVector
+    Rattletrap.Encode.Content
+    Rattletrap.Encode.DamageStateAttribute
+    Rattletrap.Encode.DemolishAttribute
+    Rattletrap.Encode.DestroyedReplication
+    Rattletrap.Encode.Dictionary
+    Rattletrap.Encode.EnumAttribute
+    Rattletrap.Encode.ExplosionAttribute
+    Rattletrap.Encode.ExtendedExplosionAttribute
+    Rattletrap.Encode.FlaggedIntAttribute
+    Rattletrap.Encode.Float32le
+    Rattletrap.Encode.FloatAttribute
+    Rattletrap.Encode.Frame
+    Rattletrap.Encode.GameModeAttribute
+    Rattletrap.Encode.Header
+    Rattletrap.Encode.Initialization
+    Rattletrap.Encode.Int32le
+    Rattletrap.Encode.Int64Attribute
+    Rattletrap.Encode.Int64le
+    Rattletrap.Encode.Int8le
+    Rattletrap.Encode.Int8Vector
+    Rattletrap.Encode.IntAttribute
+    Rattletrap.Encode.KeyFrame
+    Rattletrap.Encode.List
+    Rattletrap.Encode.LoadoutAttribute
+    Rattletrap.Encode.LoadoutOnlineAttribute
+    Rattletrap.Encode.LoadoutsAttribute
+    Rattletrap.Encode.LoadoutsOnlineAttribute
+    Rattletrap.Encode.LocationAttribute
+    Rattletrap.Encode.Mark
+    Rattletrap.Encode.Message
+    Rattletrap.Encode.MusicStingerAttribute
+    Rattletrap.Encode.PartyLeaderAttribute
+    Rattletrap.Encode.PickupAttribute
+    Rattletrap.Encode.PlayerHistoryKeyAttribute
+    Rattletrap.Encode.PrivateMatchSettingsAttribute
+    Rattletrap.Encode.ProductAttribute
+    Rattletrap.Encode.Property
+    Rattletrap.Encode.PropertyValue
+    Rattletrap.Encode.Quaternion
+    Rattletrap.Encode.QWordAttribute
+    Rattletrap.Encode.RemoteId
+    Rattletrap.Encode.Replay
+    Rattletrap.Encode.Replication
+    Rattletrap.Encode.ReplicationValue
+    Rattletrap.Encode.ReservationAttribute
+    Rattletrap.Encode.RigidBodyStateAttribute
+    Rattletrap.Encode.Rotation
+    Rattletrap.Encode.Section
+    Rattletrap.Encode.SpawnedReplication
+    Rattletrap.Encode.StatEventAttribute
+    Rattletrap.Encode.Str
+    Rattletrap.Encode.StringAttribute
+    Rattletrap.Encode.TeamPaintAttribute
+    Rattletrap.Encode.TitleAttribute
+    Rattletrap.Encode.UniqueIdAttribute
+    Rattletrap.Encode.UpdatedReplication
+    Rattletrap.Encode.Vector
+    Rattletrap.Encode.WeldedInfoAttribute
+    Rattletrap.Encode.Word32le
+    Rattletrap.Encode.Word64le
+    Rattletrap.Encode.Word8le
+    Rattletrap.Type.AppliedDamageAttribute
+    Rattletrap.Type.Attribute
+    Rattletrap.Type.AttributeMapping
+    Rattletrap.Type.AttributeType
+    Rattletrap.Type.AttributeValue
+    Rattletrap.Type.Bitstream
+    Rattletrap.Type.BooleanAttribute
+    Rattletrap.Type.ByteAttribute
+    Rattletrap.Type.Cache
+    Rattletrap.Type.CamSettingsAttribute
+    Rattletrap.Type.ClassAttributeMap
+    Rattletrap.Type.ClassMapping
+    Rattletrap.Type.ClubColorsAttribute
+    Rattletrap.Type.Common
+    Rattletrap.Type.CompressedWord
+    Rattletrap.Type.CompressedWordVector
+    Rattletrap.Type.Content
+    Rattletrap.Type.DamageStateAttribute
+    Rattletrap.Type.DemolishAttribute
+    Rattletrap.Type.DestroyedReplication
+    Rattletrap.Type.Dictionary
+    Rattletrap.Type.EnumAttribute
+    Rattletrap.Type.ExplosionAttribute
+    Rattletrap.Type.ExtendedExplosionAttribute
+    Rattletrap.Type.FlaggedIntAttribute
+    Rattletrap.Type.Float32le
+    Rattletrap.Type.FloatAttribute
+    Rattletrap.Type.Frame
+    Rattletrap.Type.GameModeAttribute
+    Rattletrap.Type.Header
+    Rattletrap.Type.Initialization
+    Rattletrap.Type.Int32le
+    Rattletrap.Type.Int64Attribute
+    Rattletrap.Type.Int64le
+    Rattletrap.Type.Int8le
+    Rattletrap.Type.Int8Vector
+    Rattletrap.Type.IntAttribute
+    Rattletrap.Type.KeyFrame
+    Rattletrap.Type.List
+    Rattletrap.Type.LoadoutAttribute
+    Rattletrap.Type.LoadoutOnlineAttribute
+    Rattletrap.Type.LoadoutsAttribute
+    Rattletrap.Type.LoadoutsOnlineAttribute
+    Rattletrap.Type.LocationAttribute
+    Rattletrap.Type.Mark
+    Rattletrap.Type.Message
+    Rattletrap.Type.MusicStingerAttribute
+    Rattletrap.Type.PartyLeaderAttribute
+    Rattletrap.Type.PickupAttribute
+    Rattletrap.Type.PlayerHistoryKeyAttribute
+    Rattletrap.Type.PrivateMatchSettingsAttribute
+    Rattletrap.Type.ProductAttribute
+    Rattletrap.Type.Property
+    Rattletrap.Type.PropertyValue
+    Rattletrap.Type.Quaternion
+    Rattletrap.Type.QWordAttribute
+    Rattletrap.Type.RemoteId
+    Rattletrap.Type.Replay
+    Rattletrap.Type.Replication
+    Rattletrap.Type.ReplicationValue
+    Rattletrap.Type.ReservationAttribute
+    Rattletrap.Type.RigidBodyStateAttribute
+    Rattletrap.Type.Rotation
+    Rattletrap.Type.Section
+    Rattletrap.Type.SpawnedReplication
+    Rattletrap.Type.StatEventAttribute
+    Rattletrap.Type.Str
+    Rattletrap.Type.StringAttribute
+    Rattletrap.Type.TeamPaintAttribute
+    Rattletrap.Type.TitleAttribute
+    Rattletrap.Type.UniqueIdAttribute
+    Rattletrap.Type.UpdatedReplication
+    Rattletrap.Type.Vector
+    Rattletrap.Type.WeldedInfoAttribute
+    Rattletrap.Type.Word32le
+    Rattletrap.Type.Word64le
+    Rattletrap.Type.Word8le
+    Rattletrap.Utility.Bytes
+    Rattletrap.Utility.Crc
+    Rattletrap.Utility.Helper
+
 executable rattletrap
+  import: basics
+
+  build-depends: rattletrap
+  ghc-options: -rtsopts -threaded
+  hs-source-dirs: executables
   main-is: Main.hs
-  other-modules:
-      Paths_rattletrap
-  hs-source-dirs:
-      executables
-  ghc-options: -optP -Wno-nonportable-include-path -Weverything -Wno-all-missed-specialisations -Wno-implicit-prelude -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-safe -Wno-unsafe -rtsopts -threaded
-  build-depends:
-      aeson >=1.2.4 && <1.5
-    , aeson-pretty >=0.8.5 && <0.9
-    , base >=4.11.1 && <4.13
-    , binary >=0.8.5 && <0.9
-    , binary-bits >=0.5 && <0.6
-    , bytestring >=0.10.8 && <0.11
-    , containers >=0.5.10 && <0.7
-    , filepath >=1.4.1 && <1.5
-    , http-client >=0.5.10 && <0.7
-    , http-client-tls >=0.3.5 && <0.4
-    , rattletrap
-    , template-haskell >=2.13.0 && <2.15
-    , text >=1.2.3 && <1.3
-    , transformers >=0.5.2 && <0.6
+
   if flag(static)
     ld-options: -static
-  default-language: Haskell2010
 
 test-suite test
-  type: exitcode-stdio-1.0
-  main-is: Main.hs
-  other-modules:
-      Paths_rattletrap
-  hs-source-dirs:
-      tests
-  ghc-options: -optP -Wno-nonportable-include-path -Weverything -Wno-all-missed-specialisations -Wno-implicit-prelude -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-safe -Wno-unsafe -rtsopts -threaded
+  import: basics
+
   build-depends:
-      HUnit >=1.6.0 && <1.7
-    , aeson >=1.2.4 && <1.5
-    , aeson-pretty >=0.8.5 && <0.9
-    , base >=4.11.1 && <4.13
-    , binary >=0.8.5 && <0.9
-    , binary-bits >=0.5 && <0.6
-    , bytestring >=0.10.8 && <0.11
-    , containers >=0.5.10 && <0.7
-    , filepath >=1.4.1 && <1.5
-    , http-client >=0.5.10 && <0.7
-    , http-client-tls >=0.3.5 && <0.4
-    , rattletrap
-    , template-haskell >=2.13.0 && <2.15
-    , temporary >=1.2.1 && <1.4
-    , text >=1.2.3 && <1.3
-    , transformers >=0.5.2 && <0.6
-  default-language: Haskell2010
+    HUnit ^>= 1.6.0,
+    rattletrap,
+    temporary ^>= 1.3,
+  hs-source-dirs: tests
+  main-is: Main.hs
+  type: exitcode-stdio-1.0
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -8,7 +8,7 @@
 import qualified Data.Int as Int
 import qualified Data.Word as Word
 import qualified GHC.Clock as Clock
-import qualified Rattletrap.Console.Main as Rattletrap
+import qualified Rattletrap
 import qualified System.Exit as Exit
 import qualified System.FilePath as Path
 import qualified System.IO.Temp as Temp
