diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -9,8 +9,8 @@
 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 [2.45][], which was
-released on 2024-10-22. If a replay can be played by the Rocket League client,
+Rattletrap supports every version of Rocket League up to [2.46][], which was
+released on 2024-12-03. 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!)
 
 ## Install
@@ -28,6 +28,7 @@
 - <https://github.com/jjbott/RocketLeagueReplayParser> (C#)
 - <https://github.com/nickbabcock/rrrocket> (Rust)
 - <https://github.com/Bakkes/CPPRP> (C++)
+- <https://github.com/Drogebot/RocketRP> (C#)
 
 ## Replays
 
@@ -127,6 +128,6 @@
 
 [Rattletrap]: https://github.com/tfausak/rattletrap
 [Rocket League]: https://www.rocketleague.com
-[2.45]: https://www.rocketleague.com/en/news/patch-notes-v2-45
+[2.46]: https://www.rocketleague.com/en/news/patch-notes-v2-46
 [Ball Chasing]: https://ballchasing.com
 [the latest release]: https://github.com/tfausak/rattletrap/releases/latest
diff --git a/rattletrap.cabal b/rattletrap.cabal
--- a/rattletrap.cabal
+++ b/rattletrap.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name: rattletrap
-version: 14.0.0
+version: 14.1.0
 synopsis: Parse and generate Rocket League replays.
 description: Rattletrap parses and generates Rocket League replays.
 build-type: Simple
@@ -110,6 +110,7 @@
     Rattletrap.Type.Attribute.CamSettings
     Rattletrap.Type.Attribute.ClubColors
     Rattletrap.Type.Attribute.CustomDemolish
+    Rattletrap.Type.Attribute.CustomDemolishExtended
     Rattletrap.Type.Attribute.DamageState
     Rattletrap.Type.Attribute.Demolish
     Rattletrap.Type.Attribute.Enum
@@ -169,6 +170,7 @@
     Rattletrap.Type.List
     Rattletrap.Type.Mark
     Rattletrap.Type.Message
+    Rattletrap.Type.ObjectTarget
     Rattletrap.Type.Property
     Rattletrap.Type.Property.Array
     Rattletrap.Type.Property.Bool
diff --git a/src/lib/Rattletrap/Console/Main.hs b/src/lib/Rattletrap/Console/Main.hs
--- a/src/lib/Rattletrap/Console/Main.hs
+++ b/src/lib/Rattletrap/Console/Main.hs
@@ -21,6 +21,7 @@
 import qualified Rattletrap.Type.Attribute.CamSettings as Attribute.CamSettings
 import qualified Rattletrap.Type.Attribute.ClubColors as Attribute.ClubColors
 import qualified Rattletrap.Type.Attribute.CustomDemolish as Attribute.CustomDemolish
+import qualified Rattletrap.Type.Attribute.CustomDemolishExtended as Attribute.CustomDemolishExtended
 import qualified Rattletrap.Type.Attribute.DamageState as Attribute.DamageState
 import qualified Rattletrap.Type.Attribute.Demolish as Attribute.Demolish
 import qualified Rattletrap.Type.Attribute.Enum as Attribute.Enum
@@ -78,6 +79,7 @@
 import qualified Rattletrap.Type.List as RList
 import qualified Rattletrap.Type.Mark as Mark
 import qualified Rattletrap.Type.Message as Message
+import qualified Rattletrap.Type.ObjectTarget as ObjectTarget
 import qualified Rattletrap.Type.Property as Property
 import qualified Rattletrap.Type.Property.Array as Property.Array
 import qualified Rattletrap.Type.Property.Byte as Property.Byte
@@ -180,6 +182,7 @@
                 Attribute.CamSettings.schema,
                 Attribute.ClubColors.schema,
                 Attribute.CustomDemolish.schema,
+                Attribute.CustomDemolishExtended.schema,
                 Attribute.DamageState.schema,
                 Attribute.Demolish.schema,
                 Attribute.Enum.schema,
@@ -238,6 +241,7 @@
                 RList.schema Attribute.Product.schema,
                 Mark.schema,
                 Message.schema,
+                ObjectTarget.schema,
                 Property.schema,
                 Property.Array.schema Property.schema,
                 Property.Byte.schema,
diff --git a/src/lib/Rattletrap/Data.hs b/src/lib/Rattletrap/Data.hs
--- a/src/lib/Rattletrap/Data.hs
+++ b/src/lib/Rattletrap/Data.hs
@@ -329,6 +329,7 @@
         ("TAGame.Car_TA:ReplicatedCarScale", AttributeType.Float),
         ("TAGame.Car_TA:ReplicatedDemolish_CustomFX", AttributeType.CustomDemolish),
         ("TAGame.Car_TA:ReplicatedDemolish", AttributeType.Demolish),
+        ("TAGame.Car_TA:ReplicatedDemolishExtended", AttributeType.CustomDemolishExtended),
         ("TAGame.Car_TA:ReplicatedDemolishGoalExplosion", AttributeType.CustomDemolish),
         ("TAGame.Car_TA:RumblePickups", AttributeType.FlaggedInt),
         ("TAGame.Car_TA:TeamPaint", AttributeType.TeamPaint),
diff --git a/src/lib/Rattletrap/Type/Attribute/CustomDemolishExtended.hs b/src/lib/Rattletrap/Type/Attribute/CustomDemolishExtended.hs
new file mode 100644
--- /dev/null
+++ b/src/lib/Rattletrap/Type/Attribute/CustomDemolishExtended.hs
@@ -0,0 +1,71 @@
+module Rattletrap.Type.Attribute.CustomDemolishExtended where
+
+import qualified Rattletrap.BitGet as BitGet
+import qualified Rattletrap.BitPut as BitPut
+import qualified Rattletrap.Schema as Schema
+import qualified Rattletrap.Type.Attribute.CustomDemolish as CustomDemolish
+import qualified Rattletrap.Type.ObjectTarget as ObjectTarget
+import qualified Rattletrap.Type.Version as Version
+import qualified Rattletrap.Utility.Json as Json
+
+data CustomDemolishExtended = CustomDemolishExtended
+  { attackerPri :: ObjectTarget.ObjectTarget,
+    selfDemoFx :: ObjectTarget.ObjectTarget,
+    selfDemolish :: Bool,
+    customDemolish :: CustomDemolish.CustomDemolish
+  }
+  deriving (Eq, Show)
+
+instance Json.FromJSON CustomDemolishExtended where
+  parseJSON = Json.withObject "CustomDemolishExtended" $ \object -> do
+    attackerPri <- Json.required object "attacker_pri"
+    selfDemoFx <- Json.required object "self_demo_fx"
+    selfDemolish <- Json.required object "self_demolish"
+    customDemolish <- Json.required object "custom_demolish"
+    pure
+      CustomDemolishExtended
+        { attackerPri,
+          selfDemoFx,
+          selfDemolish,
+          customDemolish
+        }
+
+instance Json.ToJSON CustomDemolishExtended where
+  toJSON x =
+    Json.object
+      [ Json.pair "attacker_pri" $ attackerPri x,
+        Json.pair "self_demo_fx" $ selfDemoFx x,
+        Json.pair "self_demolish" $ selfDemolish x,
+        Json.pair "custom_demolish" $ customDemolish x
+      ]
+
+schema :: Schema.Schema
+schema =
+  Schema.named "attribute-custom-demolish-extended" $
+    Schema.object
+      [ (Json.pair "attacker_pri" $ Schema.ref ObjectTarget.schema, True),
+        (Json.pair "self_demo_fx" $ Schema.ref ObjectTarget.schema, True),
+        (Json.pair "self_demolish" $ Schema.ref Schema.boolean, True),
+        (Json.pair "custom_demolish" $ Schema.ref CustomDemolish.schema, True)
+      ]
+
+bitPut :: CustomDemolishExtended -> BitPut.BitPut
+bitPut demolishAttribute =
+  ObjectTarget.bitPut (attackerPri demolishAttribute)
+    <> ObjectTarget.bitPut (selfDemoFx demolishAttribute)
+    <> BitPut.bool (selfDemolish demolishAttribute)
+    <> CustomDemolish.bitPut (customDemolish demolishAttribute)
+
+bitGet :: Version.Version -> BitGet.BitGet CustomDemolishExtended
+bitGet version = BitGet.label "CustomDemolishExtended" $ do
+  attackerPri <- BitGet.label "attackerPri" ObjectTarget.bitGet
+  selfDemoFx <- BitGet.label "selfDemoFx" ObjectTarget.bitGet
+  selfDemolish <- BitGet.label "selfDemolish" BitGet.bool
+  customDemolish <- BitGet.label "customDemolish" $ CustomDemolish.bitGet version
+  pure
+    CustomDemolishExtended
+      { attackerPri,
+        selfDemoFx,
+        selfDemolish,
+        customDemolish
+      }
diff --git a/src/lib/Rattletrap/Type/Attribute/DamageState.hs b/src/lib/Rattletrap/Type/Attribute/DamageState.hs
--- a/src/lib/Rattletrap/Type/Attribute/DamageState.hs
+++ b/src/lib/Rattletrap/Type/Attribute/DamageState.hs
@@ -70,7 +70,7 @@
     <> BitPut.bool (unknown6 damageStateAttribute)
 
 bitGet :: Version.Version -> BitGet.BitGet DamageState
-bitGet version = BitGet.label "CustomDemolish" $ do
+bitGet version = BitGet.label "DamageState" $ do
   unknown1 <- BitGet.label "unknown1" U8.bitGet
   unknown2 <- BitGet.label "unknown2" BitGet.bool
   unknown3 <- BitGet.label "unknown3" I32.bitGet
diff --git a/src/lib/Rattletrap/Type/AttributeType.hs b/src/lib/Rattletrap/Type/AttributeType.hs
--- a/src/lib/Rattletrap/Type/AttributeType.hs
+++ b/src/lib/Rattletrap/Type/AttributeType.hs
@@ -8,6 +8,7 @@
   | CamSettings
   | ClubColors
   | CustomDemolish
+  | CustomDemolishExtended
   | DamageState
   | Demolish
   | Enum
diff --git a/src/lib/Rattletrap/Type/AttributeValue.hs b/src/lib/Rattletrap/Type/AttributeValue.hs
--- a/src/lib/Rattletrap/Type/AttributeValue.hs
+++ b/src/lib/Rattletrap/Type/AttributeValue.hs
@@ -14,6 +14,7 @@
 import qualified Rattletrap.Type.Attribute.CamSettings as CamSettings
 import qualified Rattletrap.Type.Attribute.ClubColors as ClubColors
 import qualified Rattletrap.Type.Attribute.CustomDemolish as CustomDemolish
+import qualified Rattletrap.Type.Attribute.CustomDemolishExtended as CustomDemolishExtended
 import qualified Rattletrap.Type.Attribute.DamageState as DamageState
 import qualified Rattletrap.Type.Attribute.Demolish as Demolish
 import qualified Rattletrap.Type.Attribute.Enum as Enum
@@ -63,6 +64,7 @@
   | CamSettings CamSettings.CamSettings
   | ClubColors ClubColors.ClubColors
   | CustomDemolish CustomDemolish.CustomDemolish
+  | CustomDemolishExtended CustomDemolishExtended.CustomDemolishExtended
   | DamageState DamageState.DamageState
   | Demolish Demolish.Demolish
   | Enum Enum.Enum
@@ -110,6 +112,7 @@
         fmap CamSettings $ Json.required object "cam_settings",
         fmap ClubColors $ Json.required object "club_colors",
         fmap CustomDemolish $ Json.required object "custom_demolish",
+        fmap CustomDemolishExtended $ Json.required object "custom_demolish_extended",
         fmap DamageState $ Json.required object "damage_state",
         fmap Demolish $ Json.required object "demolish",
         fmap Enum $ Json.required object "enum",
@@ -156,6 +159,7 @@
     CamSettings y -> Json.object [Json.pair "cam_settings" y]
     ClubColors y -> Json.object [Json.pair "club_colors" y]
     CustomDemolish y -> Json.object [Json.pair "custom_demolish" y]
+    CustomDemolishExtended y -> Json.object [Json.pair "custom_demolish_extended" y]
     DamageState y -> Json.object [Json.pair "damage_state" y]
     Demolish y -> Json.object [Json.pair "demolish" y]
     Enum y -> Json.object [Json.pair "enum" y]
@@ -205,6 +209,7 @@
         ("cam_settings", CamSettings.schema),
         ("club_colors", ClubColors.schema),
         ("custom_demolish", CustomDemolish.schema),
+        ("custom_demolish_extended", CustomDemolishExtended.schema),
         ("damage_state", DamageState.schema),
         ("demolish", Demolish.schema),
         ("enum", Enum.schema),
@@ -251,6 +256,7 @@
   CamSettings x -> CamSettings.bitPut x
   ClubColors x -> ClubColors.bitPut x
   CustomDemolish x -> CustomDemolish.bitPut x
+  CustomDemolishExtended x -> CustomDemolishExtended.bitPut x
   DamageState x -> DamageState.bitPut x
   Demolish x -> Demolish.bitPut x
   Enum x -> Enum.bitPut x
@@ -310,6 +316,7 @@
       AttributeType.ClubColors -> fmap ClubColors ClubColors.bitGet
       AttributeType.CustomDemolish ->
         fmap CustomDemolish $ CustomDemolish.bitGet version
+      AttributeType.CustomDemolishExtended -> fmap CustomDemolishExtended $ CustomDemolishExtended.bitGet version
       AttributeType.DamageState ->
         fmap DamageState $ DamageState.bitGet version
       AttributeType.Demolish -> fmap Demolish $ Demolish.bitGet version
diff --git a/src/lib/Rattletrap/Type/ObjectTarget.hs b/src/lib/Rattletrap/Type/ObjectTarget.hs
new file mode 100644
--- /dev/null
+++ b/src/lib/Rattletrap/Type/ObjectTarget.hs
@@ -0,0 +1,53 @@
+module Rattletrap.Type.ObjectTarget where
+
+import qualified Rattletrap.BitGet as BitGet
+import qualified Rattletrap.BitPut as BitPut
+import qualified Rattletrap.Schema as Schema
+import qualified Rattletrap.Type.I32 as I32
+import qualified Rattletrap.Utility.Json as Json
+
+data ObjectTarget = ObjectTarget
+  { isActor :: Bool,
+    targetIndex :: I32.I32
+  }
+  deriving (Eq, Show)
+
+instance Json.FromJSON ObjectTarget where
+  parseJSON = Json.withObject "ObjectTarget" $ \object -> do
+    isActor <- Json.required object "is_actor"
+    targetIndex <- Json.required object "target_index"
+    pure
+      ObjectTarget
+        { isActor,
+          targetIndex
+        }
+
+instance Json.ToJSON ObjectTarget where
+  toJSON x =
+    Json.object
+      [ Json.pair "is_actor" $ isActor x,
+        Json.pair "target_index" $ targetIndex x
+      ]
+
+schema :: Schema.Schema
+schema =
+  Schema.named "object-target" $
+    Schema.object
+      [ (Json.pair "is_actor" $ Schema.ref Schema.boolean, True),
+        (Json.pair "target_index" $ Schema.ref I32.schema, True)
+      ]
+
+bitPut :: ObjectTarget -> BitPut.BitPut
+bitPut demolishAttribute =
+  BitPut.bool (isActor demolishAttribute)
+    <> I32.bitPut (targetIndex demolishAttribute)
+
+bitGet :: BitGet.BitGet ObjectTarget
+bitGet = BitGet.label "ObjectTarget" $ do
+  isActor <- BitGet.label "isActor" BitGet.bool
+  targetIndex <- BitGet.label "targetIndex" I32.bitGet
+  pure
+    ObjectTarget
+      { isActor,
+        targetIndex
+      }
diff --git a/src/test/Main.hs b/src/test/Main.hs
--- a/src/test/Main.hs
+++ b/src/test/Main.hs
@@ -122,6 +122,7 @@
     ("79ae", "voice update replay"), -- https://github.com/tfausak/rattletrap/pull/265
     ("7bf6", "an online loadouts attribute"), -- https://github.com/tfausak/rattletrap/commit/89d02f7
     ("81d1", "gridiron"), -- https://github.com/tfausak/rattletrap/pull/180
+    ("83aa", "v2.46 replicated demolish extended"), -- https://github.com/tfausak/rattletrap/issues/316
     ("89cb", "remote user data"), -- https://github.com/tfausak/rattletrap/commit/163684f
     ("8ae5", "new painted items"), -- https://github.com/tfausak/rattletrap/pull/43
     ("92a6", "with server performance state"), -- https://github.com/tfausak/rattletrap/pull/93
