diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..b947077
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,2 @@
+node_modules/
+dist/
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..6225a60
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,41 @@
+{
+  "root": true,
+  "env": { "node": true },
+  "parser": "@typescript-eslint/parser",
+  "parserOptions": {
+    "project": ["./tsconfig.json", "./scripts/tsconfig.json"]
+  },
+  "plugins": ["@typescript-eslint", "import"],
+  "extends": [
+    "eslint:recommended",
+    "plugin:@typescript-eslint/recommended",
+    "plugin:import/recommended",
+    "plugin:import/typescript",
+    "prettier"
+  ],
+  "settings": {
+    "import/resolver": {
+      "typescript": {
+        "extensions": [".js"],
+        "extensionAlias": {
+          ".js": [".ts"]
+        },
+        "project": ["./tsconfig.json"]
+      }
+    }
+  },
+  "rules": {
+    "no-return-await": "off",
+    "@typescript-eslint/return-await": ["error", "always"],
+    "import/no-unresolved": "error",
+    "import/extensions": ["error", "never", { "js": "always" }],
+    "import/order": [
+      "warn",
+      {
+        "alphabetize": { "order": "asc", "caseInsensitive": false },
+        "groups": ["type", ["builtin", "external", "internal"], "parent", "sibling", "index", "object"],
+        "newlines-between": "always"
+      }
+    ]
+  }
+}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..07ced5b
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: wyrmbane
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.github/workflows/lint-compile-test.yml b/.github/workflows/lint-compile-test.yml
new file mode 100644
index 0000000..793fb8e
--- /dev/null
+++ b/.github/workflows/lint-compile-test.yml
@@ -0,0 +1,27 @@
+# Lint, compile and test
+name: Lint, compile and test
+
+on:
+  push:
+    branches: ['main']
+  pull_request:
+    branches: ['main']
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+
+    strategy:
+      matrix:
+        node-version: [20.x]
+
+    steps:
+      - uses: actions/checkout@v3
+      - name: Use Node.js ${{ matrix.node-version }}
+        uses: actions/setup-node@v3
+        with:
+          node-version: ${{ matrix.node-version }}
+      - run: npm install --force
+      - run: npm run lint
+      - run: npm run compile
+      - run: npm run test
diff --git a/.gitignore b/.gitignore
index 2a170a8..792a8df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,147 @@
 package-lock.json
+scripts/spawnInfodump.json
+
+# asdf
+
+.tool-versions
+
+# eslint
+
+.eslintcache
+
+# Logs
+
+logs
+_.log
+npm-debug.log_
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log\*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+
+report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
+
+# Runtime data
+
+pids
+_.pid
+_.seed
+\*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+
+lib-cov
+
+# Coverage directory used by tools like istanbul
+
+coverage
+\*.lcov
+
+# nyc test coverage
+
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+
+bower_components
+
+# node-waf configuration
+
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+
+build/Release
+
+# Dependency directories
+
 node_modules/
-build/
+jspm_packages/
+
+# TypeScript v1 declaration files
+
+typings/
+
+# TypeScript cache
+
+\*.tsbuildinfo
+
+# Optional npm cache directory
+
+.npm
+
+# Optional eslint cache
+
+.eslintcache
+
+# Microbundle cache
+
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+
+.node_repl_history
+
+# Output of 'npm pack'
+
+\*.tgz
+
+# Yarn Integrity file
+
+.yarn-integrity
+
+# dotenv environment variables file
+
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+
+.cache
+
+# Next.js build output
+
+.next
+
+# Nuxt.js build / generate output
+
+.nuxt
+dist
+
+# Gatsby files
+
+.cache/
+
+# Comment in the public line in if your project uses Gatsby and _not_ Next.js
+
+# https://nextjs.org/blog/next-9-1#public-directory-support
+
+# public
+
+# vuepress build output
+
+.vuepress/dist
+
+# Serverless directories
+
+.serverless/
+
+# FuseBox cache
+
+.fusebox/
+
+# DynamoDB Local files
+
+.dynamodb/
+
+# TernJS port file
+
+.tern-port
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000..78727f6
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,5 @@
+#!/usr/bin/env sh
+. "$(dirname -- "$0")/_/husky.sh"
+
+npx lint-staged
+npm run compile
diff --git a/.huskyrc b/.huskyrc
new file mode 100644
index 0000000..4d077c8
--- /dev/null
+++ b/.huskyrc
@@ -0,0 +1,5 @@
+{
+  "hooks": {
+    "pre-commit": "lint-staged"
+  }
+}
diff --git a/.lintstagedrc b/.lintstagedrc
new file mode 100644
index 0000000..52c2ddb
--- /dev/null
+++ b/.lintstagedrc
@@ -0,0 +1,4 @@
+{
+  "src/**/*.{js,ts}": ["eslint --cache --fix"],
+  "+(*.md|src/**/*.{js,ts,json,md})": ["prettier --write"]
+}
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..40916ca
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,3 @@
+package-lock.json
+node_modules/
+src/
diff --git a/.prettierignore b/.prettierignore
index 567609b..849ddff 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1 +1 @@
-build/
+dist/
diff --git a/.prettierrc b/.prettierrc
index 7631ff9..f5ce82a 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,5 +1,6 @@
 {
   "arrowParens": "avoid",
+  "jsxSingleQuote": true,
   "printWidth": 120,
   "quoteProps": "preserve",
   "semi": true,
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..25fa621
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+  "typescript.tsdk": "node_modules/typescript/lib"
+}
diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md
new file mode 100644
index 0000000..e6b6929
--- /dev/null
+++ b/CODE-OF-CONDUCT.md
@@ -0,0 +1,84 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our community include:
+
+- Demonstrating empathy and kindness toward other people
+- Being respectful of differing opinions, viewpoints, and experiences
+- Giving and gracefully accepting constructive feedback
+- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+- Focusing on what is best not just for us as individuals, but for the overall community
+
+Examples of unacceptable behavior include:
+
+- The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+- Trolling, insulting or derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+- Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement through this repository's issue tracker. All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the project community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
+available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
diff --git a/README.md b/README.md
index d42117b..753d020 100644
--- a/README.md
+++ b/README.md
@@ -1,222 +1,51 @@
-# ATT String Transcoder
+<p align="center">
+  <img src="./att-string-transcoder.png" alt="ATT String Transcoder" />
+</p>
 
-Allows you to decode _A Township Tale_'s save strings for analysing, and encode JS objects into ATT save strings for spawning.
-
-## ⚡️ Quick Start
-
-Add this library to your project's dependencies:
-
-```shell
-$ npm install --save att-string-transcoder
-```
+<h1 align="center">ATT String Transcoder</h1>
 
-### Decoding a string
-
-```ts
-import { decodeString } from 'att-string-transcoder';
-
-/**
- * You obtain an encoded save string by sending the `select tostring` console command.
- * See: https://docs.google.com/document/d/150PALdbZalylhkI4_iCL7Bl0X_rgvq80gJCUHik3z4I/edit?usp=sharing
- */
-const encodedString = '23644,174,23644,{...very long...},2,';
-const decodedString = decodeString(encodedString);
-```
-
-<details>
-<summary><code>decodedString</code> will contain:</summary>
-
-```ts
-const decodedString = {
-  hash: 23644,
-  size: 1392,
-  prefab: {
-    prefabObject: {
-      hash: 23644,
-      position: {
-        x: -699.1250610351562,
-        y: 128.15176391601562,
-        z: 98.96036529541016
-      },
-      rotation: {
-        x: -0.00007028286927379668,
-        y: -0.06372569501399994,
-        z: -0.0011925859143957496,
-        w: 0.9979667663574219
-      },
-      scale: 1.0000009536743164
-    },
-    components: {
-      Unknown: [],
-      NetworkRigidbody: {
-        position: {
-          x: -699.1250610351562,
-          y: 128.15176391601562,
-          z: 98.96036529541016
-        },
-        rotation: {
-          x: -0.00007028286927379668,
-          y: -0.06372569501399994,
-          z: -0.0011925859143957496,
-          w: 0.9979667663574219
-        },
-        isKinematic: false,
-        isServerSleeping: true,
-        velocity: {
-          x: 0,
-          y: 0,
-          z: 0
-        },
-        angularVelocity: {
-          x: 0,
-          y: 0,
-          z: 0
-        }
-      },
-      Pickup: {
-        lastInteractorPlayerId: 1965324787
-      },
-      LiquidContainer: {
-        canAddTo: false,
-        canRemoveFrom: true,
-        contentLevel: 0,
-        hasContent: false,
-        isCustom: false,
-        presetHash: 0,
-        customData: null
-      },
-      BasicDecay: {
-        isDisabled: false,
-        timelineEntry: 37654637031400
-      }
-    },
-    embeddedEntities: {
-      Unknown: [
-        {
-          hash: 21290,
-          isAlive: true,
-          components: {
-            Unknown: [],
-            Pickup: {
-              lastInteractorPlayerId: 1965324787
-            }
-          }
-        }
-      ]
-    },
-    childPrefabs: []
-  }
-};
-```
+<p align="center">
+  <img alt="build status" src="https://img.shields.io/github/actions/workflow/status/mdingena/att-string-transcoder/lint-compile-test.yml?style=for-the-badge" />
+  <img alt="npm version" src="https://img.shields.io/npm/v/att-string-transcoder?style=for-the-badge" />
+  <img alt="node version" src="https://img.shields.io/node/v/att-string-transcoder?style=for-the-badge">
+  <img alt="typescript version" src="https://img.shields.io/npm/dependency-version/att-string-transcoder/dev/typescript?style=for-the-badge">
+  <img alt="license" src="https://img.shields.io/npm/l/att-string-transcoder?style=for-the-badge" />
+  <a href="CODE-OF-CONDUCT.md"><img alt="contributor covenant v2.0 adopted" src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg?style=for-the-badge" /></a>
+</p>
 
-</details>
+---
 
-### Encoding a string
+Allows you to decode _A Township Tale_'s save strings for analysing, and encode JS objects into ATT save strings for spawning.
 
-<details>
-<summary>First, create a <code>blade</code> prefab object:</summary>
+⚠️ Use this library primarily when creating bots for ATT, or when building your own ATT save string project. **If you just want to make string weapons, check out our [ATT String Workshop](https://github.com/mdingena/att-string-workshop) project.**
 
-```ts
-import { Prefab, PrefabHash, PhysicalMaterialPartHash } from 'att-string-transcoder';
-
-const blade: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Large_Longsword_Blade
-  },
-  components: {
-    PhysicalMaterialPart: {
-      materialHash: PhysicalMaterialPartHash.EvinonSteelAlloy
-    },
-    DurabilityModule: {
-      integrity: 0.01
-    }
-  }
-};
-```
+## :speech_balloon: Join the community
 
-</details>
+Join the ATT string creators community for sharing and troubleshooting strings built with _ATT String Transcoder_.
 
-<details>
-<summary>Then, create a <code>guard</code> prefab object:</summary>
+<a href="https://discord.gg/XXCMeHvff7" target="_blank"><img alt="Chat with the ATT String Transcoder community on Discord" src="https://img.shields.io/discord/1130738357496979497?style=for-the-badge" /></a>
 
-```ts
-import { Prefab, PrefabHash, PhysicalMaterialPartHash } from 'att-string-transcoder';
-
-export const guard: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Large_Guard_Rectangle
-  },
-  components: {
-    PhysicalMaterialPart: {
-      materialHash: PhysicalMaterialPartHash.Copper
-    },
-    DurabilityModule: {
-      integrity: 0.01
-    }
-  },
-  childPrefabs: [
-    {
-      parentHash: 51896,
-      prefab: blade
-    }
-  ]
-};
-```
+## :sparkles: Quickstart
 
-</details>
+### Installation
 
-<details>
-<summary>Finally, create a <code>handle</code> prefab object:</summary>
+Add this library to your project's dependencies:
 
-```ts
-import { Prefab, PrefabHash } from 'att-string-transcoder';
-
-const position = {
-  x: -701,
-  y: 128.2,
-  z: 100
-};
-
-export const handle: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Handle_Short,
-    position
-  },
-  components: {
-    NetworkRigidbody: {
-      position
-    }
-  },
-  childPrefabs: [
-    {
-      parentHash: 6136,
-      prefab: guard
-    }
-  ]
-};
+```shell
+npm install --save att-string-transcoder
 ```
 
-</details>
-
-Encode the hierarchical prefab object to obtain a string for spawning:
+### Usage
 
 ```ts
-import { createString } from 'att-string-transcoder';
-
-/* ... defined prefab objects ... */
+import { Prefab } from 'att-string-transcoder';
 
-/**
- * You spawn an encoded save string by sending the `spawn string-raw` console command.
- * See: https://docs.google.com/document/d/150PALdbZalylhkI4_iCL7Bl0X_rgvq80gJCUHik3z4I/edit?usp=sharing
- */
-const encodedSword = createString(handle);
-```
-
-<details>
-<summary><code>encodedSword</code> will contain:</summary>
+const blade = new Prefab('Large_Longsword_Blade').setMaterial('Mythril');
 
-```
-42230,252,42230,3291430912,1124086579,1120403456,0,0,0,1065353216,1065353216,2290978823,418,3291430912,1124086579,1120403456,0,0,0,1065353216,0,0,0,0,0,0,0,0,536871679,1163,0,0,0,0,0,0,133169152,133169152,34023564,2684354564,2523,1307670851,3758096388,126122721,1073741824,0,268438699,2147487155,3221225472,0,0,0,0,0,66584576,66584576,17011782,1342177282,1968,3875060897,4026531842,63061360,2684354560,0,0,|3,2290978823,1,272188517,1,1871432223,1,
+const handle = new Prefab('Handle_Short_Cool')
+  .addChildPrefab('Slot_Large_SwordType_Craft_33946', blade)
+  .setKinematic()
+  .print();
 ```
 
-</details>
+Read the [API Reference Documentation](docs/README.md) for more options.
diff --git a/att-string-transcoder.png b/att-string-transcoder.png
new file mode 100644
index 0000000..c123b72
Binary files /dev/null and b/att-string-transcoder.png differ
diff --git a/docs/ATTPrefabHash.md b/docs/ATTPrefabHash.md
new file mode 100644
index 0000000..0678a39
--- /dev/null
+++ b/docs/ATTPrefabHash.md
@@ -0,0 +1,5 @@
+# `<ATTPrefabHash>`
+
+The `<ATTPrefabHash>` type is used to narrow `<number>` types to recognised ATT prefab hashes.
+
+You can use the [`isATTPrefabHash(hash)`](./isATTPrefabHash.md) type assertion function to narrow down your `<number>` types.
diff --git a/docs/ATTPrefabName.md b/docs/ATTPrefabName.md
new file mode 100644
index 0000000..5e21d81
--- /dev/null
+++ b/docs/ATTPrefabName.md
@@ -0,0 +1,5 @@
+# `<ATTPrefabName>`
+
+The `<ATTPrefabName>` type is used to narrow `<string>` types to recognised ATT prefab names.
+
+You can use the [`isATTPrefabName(name)`](./isATTPrefabName.md) type assertion function to narrow down your `<string>` types.
diff --git a/docs/BasicDecayComponent.md b/docs/BasicDecayComponent.md
new file mode 100644
index 0000000..a76c474
--- /dev/null
+++ b/docs/BasicDecayComponent.md
@@ -0,0 +1,131 @@
+# Class: `BasicDecayComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<BasicDecayComponentProps>`](#basicdecaycomponentprops)
+- [Constructors](#constructors)
+  - [`new BasicDecayComponent(props)`](#new-basicdecaycomponentprops)
+  - [`BasicDecayComponent.fromBinary(reader, version)`](#basicdecaycomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`isDisabled`](#isdisabled)
+  - [`timelineEntry`](#timelineentry)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<BasicDecayComponentProps>`
+
+A portion of the configuration object to pass to the `BasicDecayComponent` constructor.
+
+```ts
+type BasicDecayComponentPropsV3 = {
+  isDisabled?: boolean | undefined;
+  timelineEntry?: number | undefined;
+};
+
+type BasicDecayComponentProps = BasicDecayComponentPropsV3;
+```
+
+#### Since v3
+
+- `isDisabled` (optional, default `true`) `<boolean>`
+- `timelineEntry` (optional, default `31557600000000000`) `<number>`
+
+## Constructors
+
+### `new BasicDecayComponent(props)`
+
+Creates a versioned `BasicDecay` component.
+
+- `props` [`<ComponentProps & BasicDecayComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<BasicDecayComponent>`
+
+```ts
+import { BasicDecayComponent } from 'att-string-transcoder';
+
+const componentVersion = 3;
+const component = new BasicDecayComponent({ version: componentVersion });
+```
+
+---
+
+### `BasicDecayComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `isDisabled`
+
+- Since: `v3`
+- `<boolean>`
+
+```ts
+import { BasicDecayComponent } from 'att-string-transcoder';
+
+const componentVersion = 3;
+const component = new BasicDecayComponent({ version: componentVersion });
+
+const isDisabled = component.isDisabled;
+// `isDisabled` is `true`
+```
+
+---
+
+### `timelineEntry`
+
+- Since: `v3`
+- `<number>`
+
+```ts
+import { BasicDecayComponent } from 'att-string-transcoder';
+
+const componentVersion = 3;
+const component = new BasicDecayComponent({ version: componentVersion });
+
+const timelineEntry = component.timelineEntry;
+// `timelineEntry` is `31557600000000000`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/BinaryData.md b/docs/BinaryData.md
new file mode 100644
index 0000000..a039140
--- /dev/null
+++ b/docs/BinaryData.md
@@ -0,0 +1,455 @@
+# Class: `BinaryData`
+
+- [Types](#types)
+  - [`<BinaryDataOptions>`](#binarydataoptions)
+  - [`<UnpackFloatOptions>`](#unpackfloatoptions)
+- [Constructors](#constructors)
+  - [`new BinaryData(binary, options?)`](#new-binarydatabinary-options)
+  - [`BinaryData.fromBoolean(boolean, options?)`](#binarydatafrombooleanboolean-options)
+  - [`BinaryData.fromChar(char, options?)`](#binarydatafromcharchar-options)
+  - [`BinaryData.fromFloat(float, options?)`](#binarydatafromfloatfloat-options)
+  - [`BinaryData.fromNumber(number, options?)`](#binarydatafromnumbernumber-options)
+  - [`BinaryData.fromSignedInteger(signedInteger, options?)`](#binarydatafromsignedintegersignedinteger-options)
+  - [`BinaryData.fromUnsignedInteger(unsignedInteger, options?)`](#binarydatafromunsignedintegerunsignedinteger-options)
+  - [`BinaryData.fromUnsignedIntegerArray(unsignedIntegerArray, options?)`](#binarydatafromunsignedintegerarrayunsignedintegerarray-options)
+  - [`BinaryData.fromUnsignedLong(unsignedLong, options?)`](#binarydatafromunsignedlongunsignedlong-options)
+  - [`BinaryData.fromUnsignedShort(unsignedShort, options?)`](#binarydatafromunsignedshortunsignedshort-options)
+- [Methods](#methods)
+  - [`BinaryData.isBinaryString(data)`](#binarydataisbinarystringdata)
+  - [`BinaryData.isSaveString(data)`](#binarydataissavestringdata)
+  - [`BinaryData.packFloat(number)`](#binarydatapackfloatnumber)
+  - [`BinaryData.unpackFloat(unsignedInteger, options?)`](#binarydataunpackfloatunsignedinteger)
+  - [`toBinaryString()`](#tobinarystring)
+  - [`toBoolean()`](#toboolean)
+  - [`toChar()`](#tochar)
+  - [`toFloat()`](#tofloat)
+  - [`toNumber()`](#tonumber)
+  - [`toSignedInteger()`](#tosignedinteger)
+  - [`toUnsignedInteger()`](#tounsignedinteger)
+  - [`toUnsignedIntegerArray()`](#tounsignedintegerarray)
+  - [`toUnsignedLong()`](#tounsignedlong)
+  - [`toUnsignedShort()`](#tounsignedshort)
+
+## Types
+
+### `<BinaryDataOptions>`
+
+A configuration object to optionally pass to the `BinaryData` constructor. Any properties that you do not pass will be created with a default value.
+
+```ts
+type BinaryDataOptions = {
+  signedIntegerOffset?: number;
+};
+```
+
+- `signedIntegerOffset` (optional, default `2147483648`) `<number>` The numeric offset used to (de)serialise signed integers.
+
+## Constructors
+
+### `new BinaryData(binary, options?)`
+
+Creates a data structure from the given binary `data` and lets you express it as other data types. You may optionally provide additional options in the second argument.
+
+- `binary` `<string>` The string containing binary data.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('11110111001100010000', {
+  signedIntegerOffset: 2147483648
+});
+```
+
+---
+
+### `BinaryData.fromBoolean(boolean, options?)`
+
+Creates a BinaryData instance from the given boolean.
+
+- `boolean` `<boolean>` The boolean from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromBoolean(true);
+```
+
+---
+
+### `BinaryData.fromChar(char, options?)`
+
+Creates a BinaryData instance from the given character.
+
+- `char` `<string>` The single string character from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromChar('x');
+```
+
+---
+
+### `BinaryData.fromFloat(float, options?)`
+
+Creates a BinaryData instance from the given floating point number.
+
+- `float` `<number>` The floating point number from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromFloat(0.69);
+```
+
+---
+
+### `BinaryData.fromNumber(number, options?)`
+
+Creates a BinaryData instance from the given number.
+
+- `number` `<number>` The number from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromNumber(1337);
+```
+
+---
+
+### `BinaryData.fromSignedInteger(signedInteger, options?)`
+
+Creates a BinaryData instance from the given signed integer.
+
+- `signedInteger` `<number>` The signed integer from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromSignedInteger(-420);
+```
+
+---
+
+### `BinaryData.fromUnsignedInteger(unsignedInteger, options?)`
+
+Creates a BinaryData instance from the given unsigned integer.
+
+- `unsignedInteger` `<number>` The unsigned integer from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromUnsignedInteger(69420);
+```
+
+---
+
+### `BinaryData.fromUnsignedIntegerArray(unsignedIntegerArray, options?)`
+
+Creates a BinaryData instance from the given comma-separated array of unsigned integers.
+
+- `unsignedIntegerArray` `<number[]>` The array of unsigned integers from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromUnsignedIntegerArray([69420, 133769]);
+```
+
+---
+
+### `BinaryData.fromUnsignedLong(unsignedLong, options?)`
+
+Creates a BinaryData instance from the given unsigned long integer.
+
+- `unsignedLong` `<number>` The unsigned long integer from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromUnsignedLong(133742069);
+```
+
+---
+
+### `BinaryData.fromUnsignedShort(unsignedShort, options?)`
+
+Creates a BinaryData instance from the given unsigned short integer.
+
+- `unsignedShort` `<number>` The unsigned short integer from which to create the BinaryData instance.
+- `options` (optional) [`<BinaryDataOptions>`](#binarydataoptions) Additional configuration options.
+- Returns: `<BinaryData>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = BinaryData.fromUnsignedShort(420);
+```
+
+## Methods
+
+### `BinaryData.isBinaryString(data)`
+
+Confirms whether `data` is a string of binary data, i.e. a string of zeroes and ones.
+
+:bulb: This is also a type assertion function, so if the passed `<string>` is asserted as a `<BinaryString>`, it will be considered as such after calling this function.
+
+- `data` `<string>` The string data to confirm is a [`<BinaryString>`](./BinaryString.md).
+- Returns: `<boolean>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const maybeBinaryString = '11110111001100010000';
+// `maybeBinaryString` is of type `string`
+
+if (BinaryData.isBinaryString(maybeBinaryString)) {
+  // `maybeBinaryString` is of type `BinaryString` inside this closure
+}
+```
+
+---
+
+### `BinaryData.isSaveString(data)`
+
+Confirms whether `data` is a string of unsigned integers and chunk versioning pairs.
+
+:bulb: This is also a type assertion function, so if the passed `<string>` is asserted as a `<SaveString>`, it will be considered as such after calling this function.
+
+- `data` `<string>` The string data to confirm is a [`<SaveString>`](./SaveString.md).
+- Returns: `<boolean>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const maybeSaveString = '...';
+// `maybeSaveString` is of type `string`
+
+if (BinaryData.isSaveString(maybeSaveString)) {
+  // `maybeSaveString` is of type `SaveString` inside this closure
+}
+```
+
+---
+
+### `BinaryData.packFloat(number)`
+
+Converts a JavaScript floating point number into an IEEE754 integer.
+
+- `number` `<number>` The number to pack as an IEEE754 integer.
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const packedFloat = BinaryData.packFloat(1337.42069);
+// `packedFloat` is `1151806838`
+```
+
+---
+
+### `BinaryData.unpackFloat(unsignedInteger)`
+
+Converts an IEEE754 integer into a JavaScript floating point number.
+
+- `unsignedInteger` `<number>` The IEEE754 integer to unpack as a floating point number.
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const unpackedFloat = BinaryData.unpackFloat(1151806838);
+// `unpackedFloat` is approximately `1337.42069`
+```
+
+---
+
+### `toBinaryString()`
+
+Returns the binary data as a `BinaryString`.
+
+- Returns: [`<BinaryString>`](./BinaryString.md)
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('1111011100110001000');
+
+const binary = data.toBinaryString();
+// `binary` is `'1111011100110001000'`
+```
+
+---
+
+### `toBoolean()`
+
+Returns the boolean represenation of the binary data.
+
+- Returns: `<boolean>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('1');
+
+const boolean = data.toBoolean();
+// `boolean` is `true`
+```
+
+---
+
+### `toChar()`
+
+Returns the character represenation of the binary data.
+
+- Returns: `<string>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('01000001');
+
+const char = data.toChar();
+// `char` is `'A'`
+```
+
+---
+
+### `toFloat()`
+
+Returns the floating point number represenation of the binary data.
+
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('01000100101001110010110101110110');
+
+const float = data.toFloat();
+// `float` is approximately `1337.42069`
+```
+
+---
+
+### `toNumber()`
+
+Returns the numeric represenation of the binary data.
+
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('10100111001');
+
+const number = data.toNumber();
+// `number` is `1337`
+```
+
+---
+
+### `toSignedInteger()`
+
+Returns the signed integer representation of the binary data.
+
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('01010110100111110101010000000111');
+
+const signedInteger = data.toSignedInteger();
+// `signedInteger` is `-694201337`
+```
+
+---
+
+### `toUnsignedInteger()`
+
+Returns the unsigned integer representation of the binary data.
+
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('00000111111110001011110111110101');
+
+const unsignedInteger = data.toUnsignedInteger();
+// `unsignedInteger` is `133742069`
+```
+
+---
+
+### `toUnsignedIntegerArray()`
+
+Returns the binary data as a comma-separated array of unsigned integers.
+
+- Returns: `<Array<number>>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData(
+  '000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101'
+);
+
+const unsignedIntegers = data.toUnsignedIntegerArray();
+// `unsignedIntegers` is `[1337, 420, 69]`
+```
+
+---
+
+### `toUnsignedLong()`
+
+Returns the unsigned long integer representation of the binary data.
+
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('0000011111111000101111011111010100000000000000000000000000000000');
+
+const unsignedLongInteger = data.toUnsignedLong();
+// `unsignedLongInteger` is `133742069`
+```
+
+---
+
+### `toUnsignedShort()`
+
+Returns the unsigned short integer representation of the binary data.
+
+- Returns: `<number>`
+
+```ts
+import { BinaryData } from 'att-string-transcoder';
+
+const data = new BinaryData('0000010100111001');
+
+const unsignedShortInteger = data.toUnsignedShort();
+// `unsignedShortInteger` is `1337`
+```
diff --git a/docs/BinaryReader.md b/docs/BinaryReader.md
new file mode 100644
index 0000000..abab98b
--- /dev/null
+++ b/docs/BinaryReader.md
@@ -0,0 +1,201 @@
+# Class: `BinaryReader`
+
+- [Constructors](#constructors)
+  - [`new BinaryReader(data)`](#new-binaryreaderdata)
+- [Methods](#methods)
+  - [`readBits(bitCount)`](#readbitsbitcount)
+  - [`readBoolean(options?)`](#readbooleanoptions)
+  - [`readChar(options?)`](#readcharoptions)
+  - [`readFloat(options?)`](#readfloatoptions)
+  - [`readSignedInteger(options?)`](#readsignedintegeroptions)
+  - [`readString(options?)`](#readstringoptions)
+  - [`readUnsignedInteger(options?)`](#readunsignedintegeroptions)
+  - [`readUnsignedLong(options?)`](#readunsignedlongoptions)
+  - [`readUnsignedShort(options?)`](#readunsignedshortoptions)
+
+## Constructors
+
+### `new BinaryReader(data)`
+
+Creates a reader to extract information from `data` using various read methods.
+
+- `data` `<string>` The binary data to read information from. May only contain `"0"` and `"1"`.
+- Returns: `<BinaryReader>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('11110111001100010000');
+```
+
+## Methods
+
+### `readBits(bitCount)`
+
+Reads the next `bitCount` bits from the binary string.
+
+- `bitCount` `<number>` The amount of bits to read from the current position of the binary data pointer.
+- Returns: [`<BinaryString>`](./BinaryString.md)
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('11110111001100010000');
+
+const firstByte = reader.readBits(8);
+// `firstByte` is `'11110111'`
+```
+
+---
+
+### `readBoolean(options?)`
+
+Reads the next bit from the binary string and returns `true` for `"1"` and `false` for `"0"`.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<boolean>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('10');
+
+const boolean1 = reader.readBoolean();
+// `boolean1` is `true`
+const boolean2 = reader.readBoolean();
+// `boolean2` is `false`
+```
+
+---
+
+### `readChar(options?)`
+
+Reads the next 8 bits from the binary string and returns the reconstructed string character.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<string>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('01000001011000100110001101000100');
+
+const char1 = reader.readChar();
+// `char1` is `'A'`
+const char2 = reader.readChar();
+// `char2` is `'b'`
+const char3 = reader.readChar();
+// `char3` is `'c'`
+const char4 = reader.readChar();
+// `char4` is `'D'`
+```
+
+---
+
+### `readFloat(options?)`
+
+Reads the next 32 bits from the binary string and returns the reconstructed floating point number.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<number>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('01000100101001110010110101110110');
+
+const float = reader.readFloat();
+// `float` is approximately `1337.42069`
+```
+
+---
+
+### `readSignedInteger(options?)`
+
+Reads the next 32 bits from the binary string and returns the reconstructed signed integer.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<number>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('01010110100111110101010000000111');
+
+const signedInteger = reader.readSignedInteger();
+// `signedInteger` is `-694201337`
+```
+
+---
+
+### `readString(options?)`
+
+Reads the next 16 bits from the binary string, then reads the number of bits as instructed and returns the reconstructed string text.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<number>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader(
+  '000000000000110101001000011001010010110001101111011011000110110001110010011011110111011100100000011011000110010000100001'
+);
+
+const string = reader.readString();
+// `string` is `'Hello, world!'`
+```
+
+---
+
+### `readUnsignedInteger(options?)`
+
+Reads the next 32 bits from the binary string and returns the reconstructed unsigned integer.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<number>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('00000111111110001011110111110101');
+
+const unsignedInteger = reader.readUnsignedInteger();
+// `unsignedInteger` is `133742069`
+```
+
+---
+
+### `readUnsignedLong(options?)`
+
+Reads the next 64 bits from the binary string and returns the reconstructed unsigned long integer.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<number>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('0000011111111000101111011111010100000000000000000000000000000000');
+
+const unsignedLongInteger = reader.readUnsignedLong();
+// `unsignedLongInteger` is `133742069`
+```
+
+---
+
+### `readUnsignedShort(options?)`
+
+Reads the next 16 bits from the binary string and returns the reconstructed unsigned short integer.
+
+- `options` (optional) [`<BinaryDataOptions>`](./BinaryData.md#binarydataoptions) Configuration options for `BinaryData`.
+- Returns: `<number>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('0000010100111001');
+
+const unsignedShortInteger = reader.readUnsignedShort();
+// `unsignedShortInteger` is `1337`
+```
diff --git a/docs/BinaryString.md b/docs/BinaryString.md
new file mode 100644
index 0000000..5c30830
--- /dev/null
+++ b/docs/BinaryString.md
@@ -0,0 +1,5 @@
+# `<BinaryString>`
+
+The `<BinaryString>` type is used to narrow `<string>` types to those containing only `"0"` and `"1"` characters.
+
+You can use the [`BinaryData.isBinaryString`](./BinaryData.md#binarydataisbinarystring) type assertion function to narrow down your `<string>` types.
diff --git a/docs/BinaryWriter.md b/docs/BinaryWriter.md
new file mode 100644
index 0000000..bc94043
--- /dev/null
+++ b/docs/BinaryWriter.md
@@ -0,0 +1,203 @@
+# Class: `BinaryWriter`
+
+- [Constructors](#constructors)
+  - [`new BinaryWriter()`](#new-binarywriter)
+- [Methods](#methods)
+  - [`flush()`](#flush)
+  - [`writeBits(data)`](#writebitsdata)
+  - [`writeBoolean(boolean)`](#writebooleanboolean)
+  - [`writeChar(char)`](#writecharchar)
+  - [`writeFloat(float)`](#writefloatfloat)
+  - [`writeSignedInteger(signedInteger)`](#writesignedintegersignedinteger)
+  - [`writeString(string)`](#writestringstring)
+  - [`writeUnsignedInteger(unsignedInteger)`](#writeunsignedintegerunsignedinteger)
+  - [`writeUnsignedLong(unsignedLong)`](#writeunsignedlongunsignedlong)
+  - [`writeUnsignedShort(unsignedShort)`](#writeunsignedshortunsignedshort)
+
+## Constructors
+
+### `new BinaryWriter()`
+
+Creates a writer to store information using various write methods.
+
+- Returns: `<BinaryWriter>`
+
+```ts
+import { BinaryReader } from 'att-string-transcoder';
+
+const reader = new BinaryReader('11110111001100010000');
+```
+
+## Methods
+
+### `flush()`
+
+Returns the stored binary string and resets the BinaryWriter's internal memory.
+
+- Returns: [`<BinaryString>`](./BinaryString.md)
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeBoolean(true); // internal memory is `'1'`
+writer.writeBoolean(true); // internal memory is `'11'`
+writer.writeBoolean(true); // internal memory is `'111'`
+
+const output = writer.flush(); // internal memory is `''`
+// `output` is `'111'`
+```
+
+---
+
+### `writeBits(data)`
+
+Writes raw binary data into BinaryWriter's internal memory.
+
+- `data` `<string>` The binary string data to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeBits('11110111001100010000');
+```
+
+---
+
+### `writeBoolean(boolean)`
+
+Writes a boolean into BinaryWriter's internal memory.
+
+- `boolean` `<boolean>` The boolean to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeBoolean(true);
+```
+
+---
+
+### `writeChar(char)`
+
+Writes a character into BinaryWriter's internal memory.
+
+- `char` `<string>` The character to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeChar('x');
+```
+
+---
+
+### `writeFloat(float)`
+
+Writes a floating point number into BinaryWriter's internal memory.
+
+- `float` `<number>` The floating point number to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeFloat(0.69);
+```
+
+---
+
+### `writeSignedInteger(signedInteger)`
+
+Writes a signed integer into BinaryWriter's internal memory.
+
+- `signedInteger` `<number>` The signed integer to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeSignedInteger(-420);
+```
+
+---
+
+### `writeString(string)`
+
+Writes a string into BinaryWriter's internal memory.
+
+- `string` `<string>` The string to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeString('Hello, world!');
+```
+
+---
+
+### `writeUnsignedInteger(unsignedInteger)`
+
+Writes an unsigned integer into BinaryWriter's internal memory.
+
+- `unsignedInteger` `<number>` The unsigned integer to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeUnsignedInteger(69420);
+```
+
+---
+
+### `writeUnsignedLong(unsignedLong)`
+
+Writes an unsigned long integer into BinaryWriter's internal memory.
+
+- `unsignedLong` `<number>` The unsigned long integer to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeUnsignedLong(133742069);
+```
+
+---
+
+### `writeUnsignedShort(unsignedShort)`
+
+Writes an unsigned short integer into BinaryWriter's internal memory.
+
+- `unsignedShort` `<number>` The unsigned short integer to store in internal memory.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+writer.writeUnsignedShort(1337);
+```
diff --git a/docs/Component.md b/docs/Component.md
new file mode 100644
index 0000000..3e32fbe
--- /dev/null
+++ b/docs/Component.md
@@ -0,0 +1,161 @@
+# Class: `Component`
+
+- [Types](#types)
+  - [`<BaseComponentProps>`](#basecomponentprops)
+  - [`<ComponentProps>`](#componentprops)
+- [Constructors](#constructors)
+  - [`new Component(props)`](#new-componentprops)
+  - [`Component.fromBinary(reader, version)`](#componentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<BaseComponentProps>`
+
+A portion of the configuration object to pass to the `Component` constructor. These properties are only present on the base `Component` class constructor and are not used in derived classes.
+
+```ts
+type BaseComponentProps = {
+  hash: number;
+  name: string;
+};
+```
+
+- `hash` `<number>` The hash of the component.
+- `name` `<string>` The name of the component.
+
+---
+
+### `<ComponentProps>`
+
+A portion of the configuration object to pass to the `Component` constructor. These properties are also used in all derived class constructors.
+
+```ts
+type ComponentProps = {
+  version: number;
+};
+```
+
+- `version` `<number>` The version of the component, which controls its data shape and (de)serialisation sequence.
+
+## Constructors
+
+### `new Component(props)`
+
+Creates a versioned component. This constructor is used internally. You shouldn't create any instances of this base class.
+
+- `props` [`<ComponentProps & BaseComponentProps>`](#basecomponentprops) Configuration of the component to create.
+- Returns: `<Component>`
+
+:warning: You shouldn't create any instances of this base class. Use any of its [derived classes](./README.md) instead.
+
+---
+
+### `Component.fromBinary(reader, version)`
+
+Reads the binary string data and returns an instantiated component.
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` instance containing the entity binary data.
+- `version` `<number>` The version of the component for interpreting the binary data.
+
+:warning: You shouldn't create any instances of this base class. Use any of its [derived classes](./README.md) instead.
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+The hash of the component.
+
+- `<number>` The hash of the component.
+
+```ts
+import { DerivedComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DerivedComponent({ version: componentVersion });
+
+const hash = component.hash;
+```
+
+---
+
+### `name`
+
+The name of the component.
+
+- `<string>` The name of the component.
+
+```ts
+import { DerivedComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DerivedComponent({ version: componentVersion });
+
+const name = component.name;
+```
+
+---
+
+### `version`
+
+The version of the component. This controls the shape of the component data and its (de)serialisation sequence when reading or writing binary data.
+
+- `<number>` The version of the component.
+
+```ts
+import { DerivedComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DerivedComponent({ version: componentVersion });
+
+const version = component.version;
+// `version` is `1`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+Returns a `BinaryString` representation of the component.
+
+- `version` (optional, default `this.version`) `<number>` The version of the component, which controls its serialisation sequence.
+- Returns: [`<BinaryString>`](./BinaryString.md)
+
+```ts
+import { DerivedComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+
+const component = new DerivedComponent({ version: componentVersion });
+
+const binaryString = component.toBinary(componentVersion);
+```
+
+---
+
+### `write(writer, version?)`
+
+Writes a `BinaryString` representation of the component to the given `BinaryWriter`, including the component hash and data length.
+
+- `writer` [`<BinaryWriter>`](./BinaryWriter.md) The `BinaryWriter` instance in which to store the binary data.
+- `version` (optional, default `this.version`) `<number>` The version of the component, which controls its serialisation sequence.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter, DerivedComponent } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+const componentVersion = 1;
+
+const component = new DerivedComponent({ version: componentVersion });
+
+component.write(writer, componentVersion);
+```
diff --git a/docs/DoorComponent.md b/docs/DoorComponent.md
new file mode 100644
index 0000000..5d51347
--- /dev/null
+++ b/docs/DoorComponent.md
@@ -0,0 +1,113 @@
+# Class: `DoorComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<DoorComponentProps>`](#doorcomponentprops)
+- [Constructors](#constructors)
+  - [`new DoorComponent(props)`](#new-doorcomponentprops)
+  - [`DoorComponent.fromBinary(reader, version)`](#doorcomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`isOpen`](#isopen)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<DoorComponentProps>`
+
+A portion of the configuration object to pass to the `DoorComponent` constructor.
+
+```ts
+type DoorComponentPropsV1 = {
+  isOpen?: number | undefined;
+};
+
+type DoorComponentProps = DoorComponentPropsV1;
+```
+
+#### Since v1
+
+- `isOpen` (optional, default `false`) `<boolean>`
+
+## Constructors
+
+### `new DoorComponent(props)`
+
+Creates a versioned `Door` component.
+
+- `props` [`<ComponentProps & DoorComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<DoorComponent>`
+
+```ts
+import { DoorComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DoorComponent({ version: componentVersion });
+```
+
+---
+
+### `DoorComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `isOpen`
+
+Reveals the open state of this component's prefab
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { DoorComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DoorComponent({ version: componentVersion });
+
+const isOpen = component.isOpen;
+// `isOpen` is `false`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/DurabilityModuleComponent.md b/docs/DurabilityModuleComponent.md
new file mode 100644
index 0000000..4cdbd1c
--- /dev/null
+++ b/docs/DurabilityModuleComponent.md
@@ -0,0 +1,113 @@
+# Class: `DurabilityModuleComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<DurabilityModuleComponentProps>`](#durabilitymodulecomponentprops)
+- [Constructors](#constructors)
+  - [`new DurabilityModuleComponent(props)`](#new-durabilitymodulecomponentprops)
+  - [`DurabilityModuleComponent.fromBinary(reader, version)`](#durabilitymodulecomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`integrity`](#integrity)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<DurabilityModuleComponentProps>`
+
+A portion of the configuration object to pass to the `DurabilityModuleComponent` constructor.
+
+```ts
+type DurabilityModuleComponentPropsV1 = {
+  integrity?: number | undefined;
+};
+
+type DurabilityModuleComponentProps = DurabilityModuleComponentPropsV1;
+```
+
+#### Since v1
+
+- `integrity` (optional, default `1`) `<number>`
+
+## Constructors
+
+### `new DurabilityModuleComponent(props)`
+
+Creates a versioned `DurabilityModule` component.
+
+- `props` [`<ComponentProps & DurabilityModuleComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<DurabilityModuleComponent>`
+
+```ts
+import { DurabilityModuleComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DurabilityModuleComponent({ version: componentVersion });
+```
+
+---
+
+### `DurabilityModuleComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `integrity`
+
+The integrity of the prefab this component is attached to.
+
+- Since: `v1`
+- `<number>` A number between `0` and `1` (inclusive).
+
+```ts
+import { DurabilityModuleComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new DurabilityModuleComponent({ version: componentVersion });
+
+const integrity = component.integrity;
+// `integrity` is `1`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/Entity.md b/docs/Entity.md
new file mode 100644
index 0000000..5bd2a2e
--- /dev/null
+++ b/docs/Entity.md
@@ -0,0 +1,310 @@
+# Class: `Entity`
+
+- [Types](#types)
+  - [`<EntityFromBinaryProps>`](#entityfrombinaryprops)
+  - [`<EntityProps>`](#entityprops)
+- [Constructors](#constructors)
+  - [`new Entity(key, props?)`](#new-entitykey-props)
+  - [`Entity.fromBinary(reader, props)`](#entityfrombinaryreader-props)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`isAlive`](#isalive)
+  - [`components`](#components)
+- [Methods](#methods)
+  - [`addComponent(component)`](#addcomponentcomponent)
+  - [`getMaterial()`](#getmaterial)
+  - [`removeAllComponents()`](#removeallcomponents)
+  - [`removeComponent(componentArg)`](#removecomponentcomponentarg)
+  - [`setMaterial(materialArg)`](#setmaterialmaterialarg)
+  - [`toBinary(componentVersions)`](#tobinarycomponentversions)
+  - [`write(writer, componentVersions)`](#writewriter-componentversions)
+
+## Types
+
+### `<EntityFromBinaryProps>`
+
+A configuration object to pass to the `fromBinary` constructor. Lets you instantiate an `Entity` from reading its binary data.
+
+```ts
+type EntityFromBinaryProps = {
+  key: string;
+  hash: number;
+  componentVersions?: Map<number, number> | undefined;
+};
+```
+
+- `key` [`EntityKey`](../src/types/EntityKey.ts) The key (`${name}_${hash}`) of the entity.
+- `hash` `<number>` The hash of the entity.
+- `componentVersions` (optional) `<Map<number, number>>` A map of component versions to assume are encoded in the binary data.
+
+---
+
+### `<EntityProps>`
+
+A configuration object to optionally pass to the `Entity` constructor. Lets you instantiate an `Entity` with predefined data. Any properties that you do not pass will be created with a default value.
+
+```ts
+type EntityProps = {
+  hash?: number | undefined;
+  isAlive?: boolean | undefined;
+  components?: (SupportedPrefabComponents & UnsupportedPrefabComponents & Partial<UnknownPrefabComponents>) | undefined;
+};
+```
+
+- `hash` (optional) `<number>` The hash of the entity.
+- `isAlive` (optional, default `true`) `<boolean>` Whether ATT considers this entity "alive".
+- `components` (optional) [`<PrefabComponents>`](../src/types/PrefabComponents.ts) A mapped object of components on the entity.
+
+## Constructors
+
+### `new Entity(key, props?)`
+
+Creates a new `Entity` object configured with the passed in configuration.
+
+- `key` [`EntityKey`](../src/types/EntityKey.ts) The key (`${name}_${hash}`) of the entity.
+- `props` (optional) [`<EntityProps>`](#entityprops) Additional configuration of the entity to create.
+- Returns: `<Entity>`
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const torchFireEntity = new Entity<'Torch'>('Fire_30100', {
+  hash: 30100,
+  isAlive: true,
+  components: {}
+});
+```
+
+:warning: This argument **must** be passed with at least the `hash` property when manually creating an unrecognised entity.
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const torchUnknownEntity = new Entity<'Torch'>('Unknown', { hash: 1337 });
+```
+
+---
+
+### `Entity.fromBinary(reader, props)`
+
+Reads the binary string data and returns an instantiated entity.
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` instance containing the entity binary data.
+- `props` [`<EntityFromBinaryProps>`](#entityfrombinaryprops) The configuration for interpreting the binary data.
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const torchFireEntity = Entity.fromBinary<'Torch'>(binaryReader, { key, hash });
+```
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding entity binary data.
+
+### `hash`
+
+The hash of the entity.
+
+- `<number>` The hash of the entity.
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const entity = new Entity<'Torch'>('Fire_30100');
+
+const hash = entity.hash;
+// `hash` is `30100`
+```
+
+---
+
+### `name`
+
+The name of the entity.
+
+- `<string>` The name of the entity.
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const entity = new Entity<'Torch'>('Fire_30100');
+
+const name = entity.name;
+// `name` is `'Fire'`
+```
+
+---
+
+### `isAlive`
+
+The alive state of the entity.
+
+- `<boolean>` The alive state of the entity.
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const entity = new Entity<'Torch'>('Fire_30100');
+
+const isAlive = entity.isAlive;
+// `isAlive` is `true`
+```
+
+---
+
+### `components`
+
+Provides access to the components stored in this entity. Components are keyed to their respective names, unless its data contained an unrecognised hash. In that case, the component will be stored in an array under the `Unknown` key.
+
+- [`<PrefabComponents>`](../src/types/PrefabComponents.ts) A map of the stored components.
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const entity = new Entity<'Torch'>('Fire_30100');
+
+const components = entity.components;
+// `components` is `{ Unknown: [] }`
+```
+
+## Methods
+
+### `addComponent(component)`
+
+Adds a `Component` to the entity. Will override any existing component with that name.
+
+- `component` [`<Component>`](./Component.md) The component to set on the entity.
+- Returns: `<this>`
+
+```ts
+import { Entity, PhysicalMaterialPartComponent, PhysicalMaterialPartHash } from 'att-string-transcoder';
+
+const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+const component = new PhysicalMaterialPartComponent({ version: 1, materialHash: PhysicalMaterialPartHash.Iron });
+
+entity.addComponent(component);
+```
+
+---
+
+### `getMaterial()`
+
+Gets the entity's physical material.
+
+- Returns: [`<PhysicalMaterialPartHash>`](../src/types/PhysicalMaterialPartHash.ts)
+
+```ts
+import { Entity, PhysicalMaterialPartHash } from 'att-string-transcoder';
+
+const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+const materialHash = entity.getMaterial();
+const materialName = PhysicalMaterialPartHash[materialHash];
+```
+
+---
+
+### `removeAllComponents()`
+
+Removes all components on this entity.
+
+- Returns: `<this>`
+
+```ts
+import { Entity } from 'att-string-transcoder';
+
+const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+entity.removeAllComponents();
+```
+
+---
+
+### `removeComponent(componentArg)`
+
+Removes the specified component from this entity.
+
+- `componentArg` `<`[`ComponentHash`](../src/types/ComponentHash.ts)` | keyof Omit<`[`PrefabComponents`](../src/types/PrefabComponents.ts)`, 'Unknown'>>` The component's hash or name to remove from this entity.
+- Returns: `<this>`
+
+```ts
+import { ComponentHash, Entity } from 'att-string-transcoder';
+
+const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+entity.removeComponent(ComponentHash.NetworkRigidbody);
+// or
+entity.removeComponent('NetworkRigidbody');
+```
+
+---
+
+### `setMaterial(materialArg)`
+
+Sets the entity's physical material. This can change both its appearance and other qualities such as durability, damage, heat retention and weight.
+
+- `materialArg` [`<PhysicalMaterialPartHash | keyof typeof PhysicalMaterialPartHash>`](../src/types/PhysicalMaterialPartHash.ts) The physical material's hash or name to set on the entity.
+- Returns: `<this>`
+
+```ts
+import { Entity, PhysicalMaterialPartHash } from 'att-string-transcoder';
+
+const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+entity.setMaterial(PhysicalMaterialPartHash.Mythril);
+// or
+entity.setMaterial('Mythril');
+```
+
+---
+
+### `toBinary(componentVersions)`
+
+Returns a `BinaryString` representation of the entity.
+
+- `componentVersions` `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: [`<BinaryString>`](./BinaryString.md)
+
+```ts
+import { ComponentHash, Entity } from 'att-string-transcoder';
+
+const torchFireEntity = new Entity<'Torch'>('Fire_30100');
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+const binaryString = torchFireEntity.toBinary(componentVersions);
+```
+
+---
+
+### `write(writer, componentVersions)`
+
+Writes a `BinaryString` representation of the entity to the given `BinaryWriter`, including the entity hash and data length.
+
+- `writer` [`<BinaryWriter>`](./BinaryWriter.md) The `BinaryWriter` instance in which to store the binary data.
+- `componentVersions` `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter, ComponentHash, Entity } from 'att-string-transcoder';
+
+const torchFireEntity = new Entity<'Torch'>('Fire_30100');
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+const writer = new BinaryWriter();
+
+torchFireEntity.write(writer, componentVersions);
+```
diff --git a/docs/FireComponent.md b/docs/FireComponent.md
new file mode 100644
index 0000000..2fa3064
--- /dev/null
+++ b/docs/FireComponent.md
@@ -0,0 +1,113 @@
+# Class: `FireComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<FireComponentProps>`](#firecomponentprops)
+- [Constructors](#constructors)
+  - [`new FireComponent(props)`](#new-firecomponentprops)
+  - [`FireComponent.fromBinary(reader, version)`](#firecomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`fuelConsumptionProgress`](#fuelconsumptionprogress)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<FireComponentProps>`
+
+A portion of the configuration object to pass to the `FireComponent` constructor.
+
+```ts
+type FireComponentPropsV1 = {
+  fuelConsumptionProgress?: number | undefined;
+};
+
+type FireComponentProps = FireComponentPropsV1;
+```
+
+#### Since v1
+
+- `fuelConsumptionProgress` (optional, default `1`) `<number>`
+
+## Constructors
+
+### `new FireComponent(props)`
+
+Creates a versioned `Fire` component.
+
+- `props` [`<ComponentProps & FireComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<FireComponent>`
+
+```ts
+import { FireComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new FireComponent({ version: componentVersion });
+```
+
+---
+
+### `FireComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `fuelConsumptionProgress`
+
+The progress of the consumption of fuel attached to this component's prefab.
+
+- Since: `v1`
+- `<number>` A number between `0` and `1` (inclusive).
+
+```ts
+import { FireComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new FireComponent({ version: componentVersion });
+
+const fuelConsumptionProgress = component.fuelConsumptionProgress;
+// `fuelConsumptionProgress` is `1`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/FuseComponent.md b/docs/FuseComponent.md
new file mode 100644
index 0000000..e76f63b
--- /dev/null
+++ b/docs/FuseComponent.md
@@ -0,0 +1,157 @@
+# Class: `FuseComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<FuseComponentProps>`](#fusecomponentprops)
+- [Constructors](#constructors)
+  - [`new FuseComponent(props)`](#new-fusecomponentprops)
+  - [`FuseComponent.fromBinary(reader, version)`](#fusecomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`isFinished`](#isfinished)
+  - [`isLit`](#islit)
+  - [`currentFuseAmount`](#currentfuseamount)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<FuseComponentProps>`
+
+A portion of the configuration object to pass to the `FuseComponent` constructor.
+
+```ts
+type FuseComponentPropsV1 = {
+  isFinished?: boolean | undefined;
+  isLit?: boolean | undefined;
+  currentFuseAmount?: number | undefined;
+};
+
+type FuseComponentProps = FuseComponentPropsV1;
+```
+
+#### Since v1
+
+- `isFinished` (optional, default `false`) `<boolean>`
+- `isLit` (optional, default `false`) `<boolean>`
+- `currentFuseAmount` (optional, default `1`) `<number>`
+
+## Constructors
+
+### `new FuseComponent(props)`
+
+Creates a versioned `Fuse` component.
+
+- `props` [`<ComponentProps & FuseComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<FuseComponent>`
+
+```ts
+import { FuseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new FuseComponent({ version: componentVersion });
+```
+
+---
+
+### `FuseComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `isFinished`
+
+Whether the fuse is finished or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { FuseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new FuseComponent({ version: componentVersion });
+
+const isFinished = component.isFinished;
+// `isFinished` is `false`
+```
+
+---
+
+### `isLit`
+
+Whether the fuse is lit or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { FuseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new FuseComponent({ version: componentVersion });
+
+const isLit = component.isLit;
+// `isLit` is `false`
+```
+
+---
+
+### `currentFuseAmount`
+
+How much of the fuse is left.
+
+- Since: `v1`
+- `<number>` A number between `0` and `1` (inclusive).
+
+```ts
+import { FuseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new FuseComponent({ version: componentVersion });
+
+const currentFuseAmount = component.currentFuseAmount;
+// `currentFuseAmount` is `1`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/HeatSourceBaseComponent.md b/docs/HeatSourceBaseComponent.md
new file mode 100644
index 0000000..60236cc
--- /dev/null
+++ b/docs/HeatSourceBaseComponent.md
@@ -0,0 +1,155 @@
+# Class: `HeatSourceBaseComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<HeatSourceBaseComponentProps>`](#heatsourcebasecomponentprops)
+- [Constructors](#constructors)
+  - [`new HeatSourceBaseComponent(props)`](#new-heatsourcebasecomponentprops)
+  - [`HeatSourceBaseComponent.fromBinary(reader, version)`](#heatsourcebasecomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`isLit`](#islit)
+  - [`progress`](#progress)
+  - [`time`](#time)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<HeatSourceBaseComponentProps>`
+
+A portion of the configuration object to pass to the `HeatSourceBaseComponent` constructor.
+
+```ts
+type HeatSourceBaseComponentPropsV1 = {
+  isLit?: boolean | undefined;
+  progress?: number | undefined;
+  time?: number | undefined;
+};
+
+export type HeatSourceBaseComponentProps = HeatSourceBaseComponentPropsV1;
+```
+
+#### Since v1
+
+- `isLit` (optional, default `true`) `<boolean>`
+- `progress` (optional, default `0`) `<number>`
+- `time` (optional, default `31557600000000000`) `<number>`
+
+## Constructors
+
+### `new HeatSourceBaseComponent(props)`
+
+Creates a versioned `HeatSourceBase` component.
+
+- `props` [`<ComponentProps & HeatSourceBaseComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<HeatSourceBaseComponent>`
+
+```ts
+import { HeatSourceBaseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new HeatSourceBaseComponent({ version: componentVersion });
+```
+
+---
+
+### `HeatSourceBaseComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `isLit`
+
+Whether this heat source is lit and active or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { HeatSourceBaseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new HeatSourceBaseComponent({ version: componentVersion });
+
+const isLit = component.isLit;
+// `isLit` is `true`
+```
+
+---
+
+### `progress`
+
+Progress of the heat source until extinguishing.
+
+- Since: `v1`
+- `<number>` A number between `0` and `1` (inclusive).
+
+```ts
+import { HeatSourceBaseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new HeatSourceBaseComponent({ version: componentVersion });
+
+const progress = component.progress;
+// `progress` is `0`
+```
+
+---
+
+### `time`
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { HeatSourceBaseComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new HeatSourceBaseComponent({ version: componentVersion });
+
+const time = component.time;
+// `time` is `31557600000000000`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LiquidContainerComponent.md b/docs/LiquidContainerComponent.md
new file mode 100644
index 0000000..7e6605c
--- /dev/null
+++ b/docs/LiquidContainerComponent.md
@@ -0,0 +1,267 @@
+# Class: `LiquidContainerComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LiquidContainerComponentProps>`](#liquidcontainercomponentprops)
+- [Constructors](#constructors)
+  - [`new LiquidContainerComponent(props)`](#new-liquidcontainercomponentprops)
+  - [`LiquidContainerComponent.fromBinary(reader, version)`](#liquidcontainercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`canAddTo`](#canaddto)
+  - [`canRemoveFrom`](#canremovefrom)
+  - [`contentLevel`](#contentlevel)
+  - [`hasContent`](#hascontent)
+  - [`isCustom`](#iscustom)
+  - [`presetHash`](#presethash)
+  - [`customData`](#customdata)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LiquidContainerComponentProps>`
+
+A portion of the configuration object to pass to the `LiquidContainerComponent` constructor.
+
+```ts
+type Color = {
+  r: number;
+  g: number;
+  b: number;
+  a: number;
+};
+
+type Effect = null | {
+  hash: number;
+  strengthMultiplier: number;
+};
+
+type FoodChunk = number;
+
+type CustomData = null | {
+  color: Color;
+  isConsumableThroughSkin: boolean;
+  visualDataHash: number;
+  effects: Effect[];
+  foodChunks: FoodChunk[];
+};
+
+type LiquidContainerComponentPropsV1 = {
+  canAddTo?: boolean | undefined;
+  canRemoveFrom?: boolean | undefined;
+  contentLevel?: number | undefined;
+  hasContent?: boolean | undefined;
+  isCustom?: boolean | undefined;
+  presetHash?: number | undefined;
+  customData?: CustomData | undefined;
+};
+
+export type LiquidContainerComponentProps = LiquidContainerComponentPropsV1;
+```
+
+#### Since v1
+
+- `canAddTo` (optional, default `false`) `<boolean>`
+- `canRemoveFrom` (optional, default `false`) `<boolean>`
+- `contentLevel` (optional, default `0`) `<number>`
+- `hasContent` (optional, default `false`) `<boolean>`
+- `isCustom` (optional, default `false`) `<boolean>`
+- `presetHash` (optional, default `0`) [`<PresetHash | 0>`](../src/types/PresetHash.ts)
+- `customData` (optional, default `null`) `<CustomData>`
+
+## Constructors
+
+### `new LiquidContainerComponent(props)`
+
+Creates a versioned `LiquidContainer` component.
+
+- `props` [`<ComponentProps & LiquidContainerComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LiquidContainerComponent>`
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+```
+
+---
+
+### `LiquidContainerComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `canAddTo`
+
+Whether any content can be added to the liquid container or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const canAddTo = component.canAddTo;
+// `canAddTo` is `false`
+```
+
+---
+
+### `canRemoveFrom`
+
+Whether any content can be removed from the liquid container or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const canRemoveFrom = component.canRemoveFrom;
+// `canRemoveFrom` is `false`
+```
+
+---
+
+### `contentLevel`
+
+The amount of content stored inside the liquid container.
+
+- Since: `v1`
+- `<number>` Any integer greater than or equal to `0`.
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const contentLevel = component.contentLevel;
+// `contentLevel` is `0`
+```
+
+---
+
+### `hasContent`
+
+Whether any content is stored in the liquid container or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const hasContent = component.hasContent;
+// `hasContent` is `false`
+```
+
+---
+
+### `isCustom`
+
+Whether the content stored in the liquid container is custom or a preset.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const isCustom = component.isCustom;
+// `isCustom` is `false`
+```
+
+---
+
+### `presetHash`
+
+The hash of the preset of the contents stored in the liquid container. Is `0` when no preset is used (uses `CustomData` instead).
+
+- Since: `v1`
+- [`<PresetHash | 0>`](../src/types/PresetHash.ts)
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const presetHash = component.presetHash;
+// `presetHash` is `0`
+```
+
+---
+
+### `customData`
+
+The data to use as the customised contents of the liquid container.
+
+- Since: `v1`
+- `<CustomData>`
+
+```ts
+import { LiquidContainerComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LiquidContainerComponent({ version: componentVersion });
+
+const customData = component.customData;
+// `customData` is `null`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicBoolReceiverComponent.md b/docs/LogicBoolReceiverComponent.md
new file mode 100644
index 0000000..f19e484
--- /dev/null
+++ b/docs/LogicBoolReceiverComponent.md
@@ -0,0 +1,113 @@
+# Class: `LogicBoolReceiverComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicBoolReceiverComponentProps>`](#logicboolreceivercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicBoolReceiverComponent(props)`](#new-logicboolreceivercomponentprops)
+  - [`LogicBoolReceiverComponent.fromBinary(reader, version)`](#logicboolreceivercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`sender`](#sender)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicBoolReceiverComponentProps>`
+
+A portion of the configuration object to pass to the `LogicBoolReceiverComponent` constructor.
+
+```ts
+type LogicBoolReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+type LogicBoolReceiverComponentProps = LogicBoolReceiverComponentPropsV1;
+```
+
+#### Since v1
+
+- `sender` (optional, default `0`) `<number>`
+
+## Constructors
+
+### `new LogicBoolReceiverComponent(props)`
+
+Creates a versioned `LogicBoolReceiver` component.
+
+- `props` [`<ComponentProps & LogicBoolReceiverComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicBoolReceiverComponent>`
+
+```ts
+import { LogicBoolReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicBoolReceiverComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicBoolReceiverComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `sender`
+
+The identifier of the `LogicBoolSender` that is connected to this `LogicBoolReceiver`.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicBoolReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicBoolReceiverComponent({ version: componentVersion });
+
+const sender = component.sender;
+// `sender` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicBoolSenderComponent.md b/docs/LogicBoolSenderComponent.md
new file mode 100644
index 0000000..84ef9af
--- /dev/null
+++ b/docs/LogicBoolSenderComponent.md
@@ -0,0 +1,179 @@
+# Class: `LogicBoolSenderComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicBoolSenderComponentProps>`](#logicboolsendercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicBoolSenderComponent(props)`](#new-logicboolsendercomponentprops)
+  - [`LogicBoolSenderComponent.fromBinary(reader, version)`](#logicboolsendercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`updatedValue`](#updatedvalue)
+  - [`changedExternally`](#changedexternally)
+  - [`identifier`](#identifier)
+  - [`value`](#value)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicBoolSenderComponentProps>`
+
+A portion of the configuration object to pass to the `LogicBoolSenderComponent` constructor.
+
+```ts
+type LogicBoolSenderComponentPropsV2 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: boolean | undefined;
+};
+
+type LogicBoolSenderComponentProps = LogicBoolSenderComponentPropsV2;
+```
+
+#### Since v2
+
+- `updatedValue` (optional, default `3171294583`) `<number>`
+- `changedExternally` (optional, default `32`) `<number>`
+- `identifier` (optional, default `0`) `<number>`
+- `value` (optional, default `false`) `<boolean>`
+
+## Constructors
+
+### `new LogicBoolSenderComponent(props)`
+
+Creates a versioned `LogicBoolSender` component.
+
+- `props` [`<ComponentProps & LogicBoolSenderComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicBoolSenderComponent>`
+
+```ts
+import { LogicBoolSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicBoolSenderComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicBoolSenderComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `updatedValue`
+
+We're not quite sure what this property does.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { LogicBoolSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicBoolSenderComponent({ version: componentVersion });
+
+const updatedValue = component.updatedValue;
+// `updatedValue` is `3171294583`
+```
+
+---
+
+### `changedExternally`
+
+We're not quite sure what this property does.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { LogicBoolSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicBoolSenderComponent({ version: componentVersion });
+
+const changedExternally = component.changedExternally;
+// `changedExternally` is `32`
+```
+
+---
+
+### `identifier`
+
+The identifier of this `LogicBoolSender` that a `LogicBoolReceiver` connects to.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { LogicBoolSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicBoolSenderComponent({ version: componentVersion });
+
+const identifier = component.identifier;
+// `identifier` is `0`
+```
+
+---
+
+### `value`
+
+The output value of this `LogicBoolSender` that a `LogicBoolReceiver` reads as its input.
+
+- Since: `v2`
+- `<boolean>`
+
+```ts
+import { LogicBoolSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicBoolSenderComponent({ version: componentVersion });
+
+const value = component.value;
+// `value` is `false`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicFloatReceiverComponent.md b/docs/LogicFloatReceiverComponent.md
new file mode 100644
index 0000000..bb0e615
--- /dev/null
+++ b/docs/LogicFloatReceiverComponent.md
@@ -0,0 +1,113 @@
+# Class: `LogicFloatReceiverComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicFloatReceiverComponentProps>`](#logicfloatreceivercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicFloatReceiverComponent(props)`](#new-logicfloatreceivercomponentprops)
+  - [`LogicFloatReceiverComponent.fromBinary(reader, version)`](#logicfloatreceivercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`sender`](#sender)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicFloatReceiverComponentProps>`
+
+A portion of the configuration object to pass to the `LogicFloatReceiverComponent` constructor.
+
+```ts
+type LogicFloatReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+type LogicFloatReceiverComponentProps = LogicFloatReceiverComponentPropsV1;
+```
+
+#### Since v1
+
+- `sender` (optional, default `0`) `<number>`
+
+## Constructors
+
+### `new LogicFloatReceiverComponent(props)`
+
+Creates a versioned `LogicFloatReceiver` component.
+
+- `props` [`<ComponentProps & LogicFloatReceiverComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicFloatReceiverComponent>`
+
+```ts
+import { LogicFloatReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatReceiverComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicFloatReceiverComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `sender`
+
+The identifier of the `LogicFloatSender` that is connected to this `LogicFloatReceiver`.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicFloatReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatReceiverComponent({ version: componentVersion });
+
+const sender = component.sender;
+// `sender` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicFloatSenderComponent.md b/docs/LogicFloatSenderComponent.md
new file mode 100644
index 0000000..4130d42
--- /dev/null
+++ b/docs/LogicFloatSenderComponent.md
@@ -0,0 +1,179 @@
+# Class: `LogicFloatSenderComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicFloatSenderComponentProps>`](#logicfloatsendercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicFloatSenderComponent(props)`](#new-logicfloatsendercomponentprops)
+  - [`LogicFloatSenderComponent.fromBinary(reader, version)`](#logicfloatsendercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`updatedValue`](#updatedvalue)
+  - [`changedExternally`](#changedexternally)
+  - [`identifier`](#identifier)
+  - [`value`](#value)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicFloatSenderComponentProps>`
+
+A portion of the configuration object to pass to the `LogicFloatSenderComponent` constructor.
+
+```ts
+type LogicFloatSenderComponentPropsV1 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: float | undefined;
+};
+
+type LogicFloatSenderComponentProps = LogicFloatSenderComponentPropsV1;
+```
+
+#### Since v1
+
+- `updatedValue` (optional, default `3171294583`) `<number>`
+- `changedExternally` (optional, default `32`) `<number>`
+- `identifier` (optional, default `0`) `<number>`
+- `value` (optional, default `0`) `<float>`
+
+## Constructors
+
+### `new LogicFloatSenderComponent(props)`
+
+Creates a versioned `LogicFloatSender` component.
+
+- `props` [`<ComponentProps & LogicFloatSenderComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicFloatSenderComponent>`
+
+```ts
+import { LogicFloatSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatSenderComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicFloatSenderComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `updatedValue`
+
+We're not quite sure what this property does.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicFloatSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatSenderComponent({ version: componentVersion });
+
+const updatedValue = component.updatedValue;
+// `updatedValue` is `3171294583`
+```
+
+---
+
+### `changedExternally`
+
+We're not quite sure what this property does.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicFloatSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatSenderComponent({ version: componentVersion });
+
+const changedExternally = component.changedExternally;
+// `changedExternally` is `32`
+```
+
+---
+
+### `identifier`
+
+The identifier of this `LogicFloatSender` that a `LogicFloatReceiver` connects to.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicFloatSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatSenderComponent({ version: componentVersion });
+
+const identifier = component.identifier;
+// `identifier` is `0`
+```
+
+---
+
+### `value`
+
+The output value of this `LogicFloatSender` that a `LogicFloatReceiver` reads as its input.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicFloatSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicFloatSenderComponent({ version: componentVersion });
+
+const value = component.value;
+// `value` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicGateReceiverComponent.md b/docs/LogicGateReceiverComponent.md
new file mode 100644
index 0000000..a256f7b
--- /dev/null
+++ b/docs/LogicGateReceiverComponent.md
@@ -0,0 +1,157 @@
+# Class: `LogicGateReceiverComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicGateReceiverComponentProps>`](#logicgatereceivercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicGateReceiverComponent(props)`](#new-logicgatereceivercomponentprops)
+  - [`LogicGateReceiverComponent.fromBinary(reader, version)`](#logicgatereceivercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`senders`](#senders)
+  - [`operationType`](#operationtype)
+  - [`isInversedOutputSaved`](#isinversedoutputsaved)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicGateReceiverComponentProps>`
+
+A portion of the configuration object to pass to the `LogicGateReceiverComponent` constructor.
+
+```ts
+type LogicGateReceiverComponentPropsV2 = {
+  senders?: number[] | undefined;
+  operationType?: LogicOperator | undefined;
+  isInversedOutputSaved?: boolean | undefined;
+};
+
+type LogicGateReceiverComponentProps = LogicGateReceiverComponentPropsV2;
+```
+
+#### Since v2
+
+- `senders` (optional, default `[]`) `<Array<number>>`
+- `operationType` (optional, default `0`) [`<LogicOperator>`](../src/types/LogicOperator.ts)
+- `isInversedOutputSaved` (optional, default `false`) `<boolean>`
+
+## Constructors
+
+### `new LogicGateReceiverComponent(props)`
+
+Creates a versioned `LogicGateReceiver` component.
+
+- `props` [`<ComponentProps & LogicGateReceiverComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicGateReceiverComponent>`
+
+```ts
+import { LogicGateReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicGateReceiverComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicGateReceiverComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `senders`
+
+The identifiers of the `Logic*Sender` components that are connected to this `LogicGateReceiver`.
+
+- Since: `v2`
+- `<Array<number>>`
+
+```ts
+import { LogicGateReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicGateReceiverComponent({ version: componentVersion });
+
+const senders = component.senders;
+// `senders` is `[]`
+```
+
+---
+
+### `operationType`
+
+The type of operation to perform on the received inputs.
+
+- Since: `v2`
+- [`<LogicOperator>`](../src/types/LogicOperator.ts)
+
+```ts
+import { LogicGateReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicGateReceiverComponent({ version: componentVersion });
+
+const operationType = component.operationType;
+// `operationType` is `0` (AND)
+```
+
+---
+
+### `isInversedOutputSaved`
+
+Whether to inverse the output of this gate.
+
+- Since: `v2`
+- `<boolean>`
+
+```ts
+import { LogicGateReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new LogicGateReceiverComponent({ version: componentVersion });
+
+const isInversedOutputSaved = component.isInversedOutputSaved;
+// `isInversedOutputSaved` is `false`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicIntReceiverComponent.md b/docs/LogicIntReceiverComponent.md
new file mode 100644
index 0000000..a8ba0e7
--- /dev/null
+++ b/docs/LogicIntReceiverComponent.md
@@ -0,0 +1,113 @@
+# Class: `LogicIntReceiverComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicIntReceiverComponentProps>`](#logicintreceivercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicIntReceiverComponent(props)`](#new-logicintreceivercomponentprops)
+  - [`LogicIntReceiverComponent.fromBinary(reader, version)`](#logicintreceivercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`sender`](#sender)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicIntReceiverComponentProps>`
+
+A portion of the configuration object to pass to the `LogicIntReceiverComponent` constructor.
+
+```ts
+type LogicIntReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+type LogicIntReceiverComponentProps = LogicIntReceiverComponentPropsV1;
+```
+
+#### Since v1
+
+- `sender` (optional, default `0`) `<number>`
+
+## Constructors
+
+### `new LogicIntReceiverComponent(props)`
+
+Creates a versioned `LogicIntReceiver` component.
+
+- `props` [`<ComponentProps & LogicIntReceiverComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicIntReceiverComponent>`
+
+```ts
+import { LogicIntReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntReceiverComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicIntReceiverComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `sender`
+
+The identifier of the `LogicIntSender` that is connected to this `LogicIntReceiver`.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicIntReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntReceiverComponent({ version: componentVersion });
+
+const sender = component.sender;
+// `sender` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicIntSenderComponent.md b/docs/LogicIntSenderComponent.md
new file mode 100644
index 0000000..bac00c6
--- /dev/null
+++ b/docs/LogicIntSenderComponent.md
@@ -0,0 +1,179 @@
+# Class: `LogicIntSenderComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicIntSenderComponentProps>`](#logicintsendercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicIntSenderComponent(props)`](#new-logicintsendercomponentprops)
+  - [`LogicIntSenderComponent.fromBinary(reader, version)`](#logicintsendercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`updatedValue`](#updatedvalue)
+  - [`changedExternally`](#changedexternally)
+  - [`identifier`](#identifier)
+  - [`value`](#value)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicIntSenderComponentProps>`
+
+A portion of the configuration object to pass to the `LogicIntSenderComponent` constructor.
+
+```ts
+type LogicIntSenderComponentPropsV1 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: number | undefined;
+};
+
+type LogicIntSenderComponentProps = LogicIntSenderComponentPropsV1;
+```
+
+#### Since v1
+
+- `updatedValue` (optional, default `3171294583`) `<number>`
+- `changedExternally` (optional, default `32`) `<number>`
+- `identifier` (optional, default `0`) `<number>`
+- `value` (optional, default `false`) `<intean>`
+
+## Constructors
+
+### `new LogicIntSenderComponent(props)`
+
+Creates a versioned `LogicIntSender` component.
+
+- `props` [`<ComponentProps & LogicIntSenderComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicIntSenderComponent>`
+
+```ts
+import { LogicIntSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntSenderComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicIntSenderComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `updatedValue`
+
+We're not quite sure what this property does.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicIntSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntSenderComponent({ version: componentVersion });
+
+const updatedValue = component.updatedValue;
+// `updatedValue` is `3171294583`
+```
+
+---
+
+### `changedExternally`
+
+We're not quite sure what this property does.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicIntSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntSenderComponent({ version: componentVersion });
+
+const changedExternally = component.changedExternally;
+// `changedExternally` is `32`
+```
+
+---
+
+### `identifier`
+
+The identifier of this `LogicIntSender` that a `LogicIntReceiver` connects to.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicIntSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntSenderComponent({ version: componentVersion });
+
+const identifier = component.identifier;
+// `identifier` is `0`
+```
+
+---
+
+### `value`
+
+The output value of this `LogicIntSender` that a `LogicIntReceiver` reads as its input.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicIntSenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicIntSenderComponent({ version: componentVersion });
+
+const value = component.value;
+// `value` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicVector3ReceiverComponent.md b/docs/LogicVector3ReceiverComponent.md
new file mode 100644
index 0000000..0708e88
--- /dev/null
+++ b/docs/LogicVector3ReceiverComponent.md
@@ -0,0 +1,113 @@
+# Class: `LogicVector3ReceiverComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicVector3ReceiverComponentProps>`](#logicvector3receivercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicVector3ReceiverComponent(props)`](#new-logicvector3receivercomponentprops)
+  - [`LogicVector3ReceiverComponent.fromBinary(reader, version)`](#logicvector3receivercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`sender`](#sender)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicVector3ReceiverComponentProps>`
+
+A portion of the configuration object to pass to the `LogicVector3ReceiverComponent` constructor.
+
+```ts
+type LogicVector3ReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+type LogicVector3ReceiverComponentProps = LogicVector3ReceiverComponentPropsV1;
+```
+
+#### Since v1
+
+- `sender` (optional, default `0`) `<number>`
+
+## Constructors
+
+### `new LogicVector3ReceiverComponent(props)`
+
+Creates a versioned `LogicVector3Receiver` component.
+
+- `props` [`<ComponentProps & LogicVector3ReceiverComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicVector3ReceiverComponent>`
+
+```ts
+import { LogicVector3ReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3ReceiverComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicVector3ReceiverComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `sender`
+
+The identifier of the `LogicVector3Sender` that is connected to this `LogicVector3Receiver`.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicVector3ReceiverComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3ReceiverComponent({ version: componentVersion });
+
+const sender = component.sender;
+// `sender` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/LogicVector3SenderComponent.md b/docs/LogicVector3SenderComponent.md
new file mode 100644
index 0000000..72dd992
--- /dev/null
+++ b/docs/LogicVector3SenderComponent.md
@@ -0,0 +1,179 @@
+# Class: `LogicVector3SenderComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<LogicVector3SenderComponentProps>`](#logicvector3sendercomponentprops)
+- [Constructors](#constructors)
+  - [`new LogicVector3SenderComponent(props)`](#new-logicvector3sendercomponentprops)
+  - [`LogicVector3SenderComponent.fromBinary(reader, version)`](#logicvector3sendercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`updatedValue`](#updatedvalue)
+  - [`changedExternally`](#changedexternally)
+  - [`identifier`](#identifier)
+  - [`value`](#value)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<LogicVector3SenderComponentProps>`
+
+A portion of the configuration object to pass to the `LogicVector3SenderComponent` constructor.
+
+```ts
+type LogicVector3SenderComponentPropsV1 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: Vector3 | undefined;
+};
+
+type LogicVector3SenderComponentProps = LogicVector3SenderComponentPropsV1;
+```
+
+#### Since v1
+
+- `updatedValue` (optional, default `3171294583`) `<number>`
+- `changedExternally` (optional, default `32`) `<number>`
+- `identifier` (optional, default `0`) `<number>`
+- `value` (optional, default `{ x: 0, y: 0, z: 0 }`) `<Vector3>`
+
+## Constructors
+
+### `new LogicVector3SenderComponent(props)`
+
+Creates a versioned `LogicVector3Sender` component.
+
+- `props` [`<ComponentProps & LogicVector3SenderComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<LogicVector3SenderComponent>`
+
+```ts
+import { LogicVector3SenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3SenderComponent({ version: componentVersion });
+```
+
+---
+
+### `LogicVector3SenderComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `updatedValue`
+
+We're not quite sure what this property does.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicVector3SenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3SenderComponent({ version: componentVersion });
+
+const updatedValue = component.updatedValue;
+// `updatedValue` is `3171294583`
+```
+
+---
+
+### `changedExternally`
+
+We're not quite sure what this property does.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicVector3SenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3SenderComponent({ version: componentVersion });
+
+const changedExternally = component.changedExternally;
+// `changedExternally` is `32`
+```
+
+---
+
+### `identifier`
+
+The identifier of this `LogicVector3Sender` that a `LogicVector3Receiver` connects to.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { LogicVector3SenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3SenderComponent({ version: componentVersion });
+
+const identifier = component.identifier;
+// `identifier` is `0`
+```
+
+---
+
+### `value`
+
+The output value of this `LogicVector3Sender` that a `LogicVector3Receiver` reads as its input.
+
+- Since: `v1`
+- `<Vector3>`
+
+```ts
+import { LogicVector3SenderComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new LogicVector3SenderComponent({ version: componentVersion });
+
+const value = component.value;
+// `value` is `{ x: 0, y: 0, z: 0 }`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/NetworkRigidbodyComponent.md b/docs/NetworkRigidbodyComponent.md
new file mode 100644
index 0000000..eb44a70
--- /dev/null
+++ b/docs/NetworkRigidbodyComponent.md
@@ -0,0 +1,219 @@
+# Class: `NetworkRigidbodyComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<NetworkRigidbodyComponentProps>`](#networkrigidbodycomponentprops)
+- [Constructors](#constructors)
+  - [`new NetworkRigidbodyComponent(props)`](#new-networkrigidbodycomponentprops)
+  - [`NetworkRigidbodyComponent.fromBinary(reader, version)`](#networkrigidbodycomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`isDisabled`](#isdisabled)
+  - [`timelineEntry`](#timelineentry)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<NetworkRigidbodyComponentProps>`
+
+A portion of the configuration object to pass to the `NetworkRigidbodyComponent` constructor.
+
+```ts
+type NetworkRigidbodyComponentPropsV1 = {
+  position?: Position | undefined;
+  rotation?: Rotation | undefined;
+  isKinematic?: boolean | undefined;
+  isServerSleeping?: boolean | undefined;
+  velocity?: Velocity | undefined;
+  angularVelocity?: AngularVelocity | undefined;
+};
+
+type NetworkRigidbodyComponentProps = NetworkRigidbodyComponentPropsV1;
+```
+
+#### Since v1
+
+- `position` (optional, default `{ x: 0, y: 0, z: 0 }`) [`<Position>`](../src/types/Position.ts)
+- `rotation` (optional, default `{ x: 0, y: 0, z: 0, w: 1 }`) [`<Rotation>`](../src/types/Rotation.ts)
+- `isKinematic` (optional, default `false`) `<boolean>`
+- `isServerSleeping` (optional, default `false`) `<boolean>`
+- `velocity` (optional, default `{ x: 0, y: 0, z: 0 }`) [`<Velocity>`](../src/types/Velocity.ts)
+- `angularVelocity` (optional, default `{ x: 0, y: 0, z: 0 }`) [`<AngularVelocity>`](../src/types/AngularVelocity.ts)
+
+## Constructors
+
+### `new NetworkRigidbodyComponent(props)`
+
+Creates a versioned `NetworkRigidbody` component.
+
+- `props` [`<ComponentProps & NetworkRigidbodyComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<NetworkRigidbodyComponent>`
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+```
+
+---
+
+### `NetworkRigidbodyComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `position`
+
+Position of the prefab this component is attached to.
+
+- Since: `v1`
+- [`<Position>`](../src/types/Position.ts)
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+const position = component.position;
+// `position` is `{ x: 0, y: 0, z: 0 }`
+```
+
+---
+
+### `rotation`
+
+Rotation of the prefab this component is attached to.
+
+- Since: `v1`
+- [`<Rotation>`](../src/types/Rotation.ts)
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+const rotation = component.rotation;
+// `rotation` is `{ x: 0, y: 0, z: 0, w: 1 }`
+```
+
+---
+
+### `isKinematic`
+
+Whether the prefab this component is attached to is [kinematic](https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html) or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+const isKinematic = component.isKinematic;
+// `isKinematic` is `false`
+```
+
+---
+
+### `isServerSleeping`
+
+Whether the prefab this component is attached to is [sleeping](https://docs.unity3d.com/Manual/RigidbodiesOverview.html) or not.
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+const isServerSleeping = component.isServerSleeping;
+// `isServerSleeping` is `false`
+```
+
+---
+
+### `velocity`
+
+Velocity of the prefab this component is attached to.
+
+- Since: `v1`
+- [`<Velocity>`](../src/types/Velocity.ts)
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+const velocity = component.velocity;
+// `velocity` is `{ x: 0, y: 0, z: 0 }`
+```
+
+---
+
+### `angularVelocity`
+
+Angular velocity of the prefab this component is attached to.
+
+- Since: `v1`
+- [`<AngularVelocity>`](../src/types/AngularVelocity.ts)
+
+```ts
+import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+const angularVelocity = component.angularVelocity;
+// `angularVelocity` is `{ x: 0, y: 0, z: 0 }`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/PhysicalMaterialPartComponent.md b/docs/PhysicalMaterialPartComponent.md
new file mode 100644
index 0000000..0f04e15
--- /dev/null
+++ b/docs/PhysicalMaterialPartComponent.md
@@ -0,0 +1,113 @@
+# Class: `PhysicalMaterialPartComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<PhysicalMaterialPartComponentProps>`](#physicalmaterialpartcomponentprops)
+- [Constructors](#constructors)
+  - [`new PhysicalMaterialPartComponent(props)`](#new-physicalmaterialpartcomponentprops)
+  - [`PhysicalMaterialPartComponent.fromBinary(reader, version)`](#physicalmaterialpartcomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`materialHash`](#materialhash)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<PhysicalMaterialPartComponentProps>`
+
+A portion of the configuration object to pass to the `PhysicalMaterialPartComponent` constructor.
+
+```ts
+type PhysicalMaterialPartComponentPropsV1 = {
+  materialHash?: number | undefined;
+};
+
+type PhysicalMaterialPartComponentProps = PhysicalMaterialPartComponentPropsV1;
+```
+
+#### Since v1
+
+- `materialHash` (optional, default `1`) [`<PhysicalMaterialPartHash>`](../src/types/PhysicalMaterialPartHash.ts)
+
+## Constructors
+
+### `new PhysicalMaterialPartComponent(props)`
+
+Creates a versioned `PhysicalMaterialPart` component.
+
+- `props` [`<ComponentProps & PhysicalMaterialPartComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<PhysicalMaterialPartComponent>`
+
+```ts
+import { PhysicalMaterialPartComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new PhysicalMaterialPartComponent({ version: componentVersion });
+```
+
+---
+
+### `PhysicalMaterialPartComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `materialHash`
+
+The hash of the physical material of the prefab this component is attached to.
+
+- Since: `v1`
+- [`<PhysicalMaterialPartHash>`](../src/types/PhysicalMaterialPartHash.ts)
+
+```ts
+import { PhysicalMaterialPartComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new PhysicalMaterialPartComponent({ version: componentVersion });
+
+const materialHash = component.materialHash;
+// `materialHash` is `1`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/PickupComponent.md b/docs/PickupComponent.md
new file mode 100644
index 0000000..84e7ecc
--- /dev/null
+++ b/docs/PickupComponent.md
@@ -0,0 +1,151 @@
+# Class: `PickupComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<PickupComponentProps>`](#pickupcomponentprops)
+- [Constructors](#constructors)
+  - [`new PickupComponent(props)`](#new-pickupcomponentprops)
+  - [`PickupComponent.fromBinary(reader, version)`](#pickupcomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`lastInteractorPlayerId`](#lastinteractorplayerid)
+  - [`dockedMemory`](#dockedmemory)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<PickupComponentProps>`
+
+A portion of the configuration object to pass to the `PickupComponent` constructor.
+
+```ts
+type GrabPointParameters = null | {
+  grabPointIndex: number;
+  lastLinearPosition: number;
+  lastPosition: Position;
+  lastRotation: Rotation;
+};
+
+type PickupComponentPropsV1 = {
+  lastInteractorPlayerId?: number | undefined;
+  dockedMemory?: never;
+};
+
+type PickupComponentPropsV2 = {
+  lastInteractorPlayerId?: number | undefined;
+  dockedMemory?: GrabPointParameters[] | undefined;
+};
+
+type PickupComponentProps = PickupComponentPropsV1 | PickupComponentPropsV2;
+```
+
+#### Since v1
+
+- `lastInteractorPlayerId` (optional, default `0`) `<number>`
+
+#### Since v2
+
+- `lastInteractorPlayerId` (optional, default `0`) `<number>`
+- `dockedMemory` (optional, default `[]`) `<Array<GrabPointParameters>>`
+
+## Constructors
+
+### `new PickupComponent(props)`
+
+Creates a versioned `Pickup` component.
+
+- `props` [`<ComponentProps & PickupComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<PickupComponent>`
+
+```ts
+import { PickupComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupComponent({ version: componentVersion });
+```
+
+---
+
+### `PickupComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `lastInteractorPlayerId`
+
+The ID of the player that last interacted with the prefab that this component is attached to.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { PickupComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupComponent({ version: componentVersion });
+
+const lastInteractorPlayerId = component.lastInteractorPlayerId;
+// `lastInteractorPlayerId` is `0`
+```
+
+---
+
+### `dockedMemory`
+
+An array of `<GrabPointParameters>` that describes the orientation of prefabs when they were docked. Used to control in which orientation pickups should be held when grabbed from the dock attached to the same prefab this component is attached to.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PickupComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupComponent({ version: componentVersion });
+
+const dockedMemory = component.dockedMemory;
+// `dockedMemory` is `[]`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/PickupDockComponent.md b/docs/PickupDockComponent.md
new file mode 100644
index 0000000..a47bb73
--- /dev/null
+++ b/docs/PickupDockComponent.md
@@ -0,0 +1,151 @@
+# Class: `PickupDockComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<PickupDockComponentProps>`](#pickupdockcomponentprops)
+- [Constructors](#constructors)
+  - [`new PickupDockComponent(props)`](#new-pickupdockcomponentprops)
+  - [`PickupDockComponent.fromBinary(reader, version)`](#pickupdockcomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`dockedTypeHash`](#dockedtypehash)
+  - [`quantity`](#quantity)
+  - [`childIndex`](#childindex)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<PickupDockComponentProps>`
+
+A portion of the configuration object to pass to the `PickupDockComponent` constructor.
+
+```ts
+type PickupDockComponentPropsV2 = {
+  dockedTypeHash?: number | undefined;
+  quantity?: number | undefined;
+  childIndex?: number | undefined;
+};
+
+type PickupDockComponentProps = PickupDockComponentPropsV2;
+```
+
+#### Since v2
+
+- `dockedTypeHash` (optional, default `0`) `<number>`
+- `quantity` (optional, default `1`) `<number>`
+- `childIndex` (optional, default `0`) `<number>`
+
+## Constructors
+
+### `new PickupDockComponent(props)`
+
+Creates a versioned `PickupDock` component.
+
+- `props` [`<ComponentProps & PickupDockComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<PickupDockComponent>`
+
+```ts
+import { PickupDockComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupDockComponent({ version: componentVersion });
+```
+
+---
+
+### `PickupDockComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `dockedTypeHash`
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PickupDockComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupDockComponent({ version: componentVersion });
+
+const dockedTypeHash = component.dockedTypeHash;
+// `dockedTypeHash` is `0`
+```
+
+---
+
+### `quantity`
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PickupDockComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupDockComponent({ version: componentVersion });
+
+const quantity = component.quantity;
+// `quantity` is `1`
+```
+
+---
+
+### `childIndex`
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PickupDockComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PickupDockComponent({ version: componentVersion });
+
+const childIndex = component.childIndex;
+// `childIndex` is `0`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/PopulationSpawnAreaComponent.md b/docs/PopulationSpawnAreaComponent.md
new file mode 100644
index 0000000..439fe0c
--- /dev/null
+++ b/docs/PopulationSpawnAreaComponent.md
@@ -0,0 +1,288 @@
+# Class: `PopulationSpawnAreaComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<PopulationSpawnAreaComponentProps>`](#populationspawnareacomponentprops)
+- [Constructors](#constructors)
+  - [`new PopulationSpawnAreaComponent(props)`](#new-populationspawnareacomponentprops)
+  - [`PopulationSpawnAreaComponent.fromBinary(reader, version)`](#populationspawnareacomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`definition`](#definition)
+  - [`isPopulationStarted`](#ispopulationstarted)
+  - [`children`](#children)
+  - [`maxPopulation`](#maxpopulation)
+  - [`currentPopulation`](#currentpopulation)
+  - [`checkPopulationTime`](#checkpopulationtime)
+  - [`numberOfSpawnPoints`](#numberofspawnpoints)
+  - [`startingPopulation`](#startingpopulation)
+  - [`isOneOff`](#isoneoff)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<PopulationSpawnAreaComponentProps>`
+
+A portion of the configuration object to pass to the `PopulationSpawnAreaComponent` constructor.
+
+```ts
+type PopulationSaveDataChild = null | {
+  index: number;
+  pointIndex: number;
+};
+
+type PopulationSpawnAreaComponentPropsV2 = {
+  definition?: number | undefined;
+  isPopulationStarted?: boolean | undefined;
+  children?: PopulationSaveDataChild[] | undefined;
+  maxPopulation?: number | undefined;
+  currentPopulation?: number | undefined;
+  checkPopulationTime?: number | undefined;
+  numberOfSpawnPoints?: number | undefined;
+  startingPopulation?: number | undefined;
+  isOneOff?: boolean | undefined;
+};
+
+type PopulationSpawnAreaComponentProps = PopulationSpawnAreaComponentPropsV2;
+```
+
+#### Since v2
+
+- `definition` (optional, default `30040`) [`<PopulationDefinitionHash>`](../src/types/PopulationDefinitionHash.ts)
+- `isPopulationStarted` (optional, default `true`) `<boolean>`
+- `children` (optional, default `[]`) `<Array<PopulationSaveDataChild>>`
+- `maxPopulation` (optional, default `20`) `<number>`
+- `currentPopulation` (optional, default `5`) `<number>`
+- `checkPopulationTime` (optional, default `852974979330`) `<number>`
+- `numberOfSpawnPoints` (optional, default `40`) `<number>`
+- `startingPopulation` (optional, default `5`) `<number>`
+- `isOneOff` (optional, default `false`) `<boolean>`
+
+## Constructors
+
+### `new PopulationSpawnAreaComponent(props)`
+
+Creates a versioned `PopulationSpawnArea` component.
+
+- `props` [`<ComponentProps & PopulationSpawnAreaComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<PopulationSpawnAreaComponent>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+```
+
+---
+
+### `PopulationSpawnAreaComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `definition`
+
+The hash of the population to spawn in the `SpawnArea` component that is attached to the same prefab this component is attached to.
+
+- Since: `v2`
+- [`<PopulationDefinitionHash>`](../src/types/PopulationDefinitionHash.ts)
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const definition = component.definition;
+// `definition` is `30040`
+```
+
+---
+
+### `isPopulationStarted`
+
+- Since: `v2`
+- `<boolean>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const isPopulationStarted = component.isPopulationStarted;
+// `isPopulationStarted` is `true`
+```
+
+---
+
+### `children`
+
+- Since: `v2`
+- `<Array<PopulationSaveDataChild>>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const children = component.children;
+// `children` is `[]`
+```
+
+---
+
+### `maxPopulation`
+
+The maximum amount of spawned prefabs in this population.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const maxPopulation = component.maxPopulation;
+// `maxPopulation` is `20`
+```
+
+---
+
+### `currentPopulation`
+
+The current amount of spawned prefabs in this population.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const currentPopulation = component.currentPopulation;
+// `currentPopulation` is `5`
+```
+
+---
+
+### `checkPopulationTime`
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const checkPopulationTime = component.checkPopulationTime;
+// `checkPopulationTime` is `852974979330`
+```
+
+---
+
+### `numberOfSpawnPoints`
+
+The amount of spawn locations inside the `SpawnArea` component that is attached to the same prefab this component is attached to.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const numberOfSpawnPoints = component.numberOfSpawnPoints;
+// `numberOfSpawnPoints` is `40`
+```
+
+---
+
+### `startingPopulation`
+
+The amount of spawned prefabs that this population begins with.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const startingPopulation = component.startingPopulation;
+// `startingPopulation` is `5`
+```
+
+---
+
+### `isOneOff`
+
+Whether any removed prefabs from this population shouldn't be replaced after the server's respawn timer has elapsed.
+
+- Since: `v2`
+- `<number>`
+
+```ts
+import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+const isOneOff = component.isOneOff;
+// `isOneOff` is `false`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/Prefab.md b/docs/Prefab.md
new file mode 100644
index 0000000..6a170f3
--- /dev/null
+++ b/docs/Prefab.md
@@ -0,0 +1,1211 @@
+# Class: `Prefab`
+
+- [Types](#types)
+  - [`<PrefabProps>`](#prefabprops)
+- [Constructors](#constructors)
+  - [`new Prefab(prefabName, props?)`](#new-prefabprefabname-props)
+  - [`Prefab.fromBinary(reader, componentVersions?)`](#prefabfrombinaryreader-componentversions)
+  - [`Prefab.fromSaveString(saveString)`](#prefabfromsavestringsavestring)
+- [Properties](#properties)
+  - [`name`](#name)
+  - [`hash`](#hash)
+  - [`position`](#position)
+  - [`rotation`](#rotation)
+  - [`scale`](#scale)
+  - [`components`](#components)
+  - [`entities`](#entities)
+  - [`children`](#children)
+- [Methods](#methods)
+  - [`addChildPrefab(parentKey, childPrefab)`](#addchildprefabparentkey-childprefab)
+  - [`addComponent(component)`](#addcomponentcomponent)
+  - [`addEntity(entity)`](#addentityentity)
+  - [`addGift(giftPrefab)`](#addgiftgiftprefab)
+  - [`clone(options?)`](#cloneoptions)
+  - [`getAngularVelocity()`](#getangularvelocity)
+  - [`getChildPrefab(prefabName, parentHash?)`](#getchildprefabprefabname-parenthash)
+  - [`getComponentVersions()`](#getcomponentversions)
+  - [`getGiftBoxLabel()`](#getgiftboxlabel)
+  - [`getIntegrity()`](#getintegrity)
+  - [`getKinematic()`](#getkinematic)
+  - [`getMaterial()`](#getmaterial)
+  - [`getOnFire()`](#getonfire)
+  - [`getPosition()`](#getposition)
+  - [`getRotation()`](#getrotation)
+  - [`getScale()`](#getscale)
+  - [`getServerSleeping()`](#getserversleeping)
+  - [`getServings()`](#getservings)
+  - [`getSpawnAreaPopulationName()`](#getspawnareapopulationname)
+  - [`getVelocity()`](#getvelocity)
+  - [`inspect()`](#inspect)
+  - [`print()`](#print)
+  - [`removeAllChildPrefabs()`](#removeallchildprefabs)
+  - [`removeAllComponents()`](#removeallcomponents)
+  - [`removeAllEntities()`](#removeallentities)
+  - [`removeAllGifts()`](#removeallgifts)
+  - [`removeChildPrefab(prefabArg)`](#removechildprefabprefabarg)
+  - [`removeComponent(componentArg)`](#removecomponentcomponentarg)
+  - [`removeEntity(entityKey)`](#removeentityentitykey)
+  - [`removeGift(prefabHash)`](#removegiftprefabhash)
+  - [`removeSpawnArea()`](#removespawnarea)
+  - [`setAngularVelocity(angularVelocity)`](#setangularvelocityangularvelocity)
+  - [`setGiftBoxLabel(label)`](#setgiftboxlabellabel)
+  - [`setIntegrity(integrity)`](#setintegrityintegrity)
+  - [`setKinematic(isKinematic?)`](#setkinematiciskinematic)
+  - [`setMaterial(materialArg)`](#setmaterialmaterialarg)
+  - [`setOnFire(isLit?)`](#setonfireislit)
+  - [`setPosition(position)`](#setpositionposition)
+  - [`setRotation(rotation)`](#setrotationrotation)
+  - [`setScale(scale)`](#setscalescale)
+  - [`setServerSleeping(isServerSleeping?)`](#setserversleepingisserversleeping)
+  - [`setServings(servings)`](#setservingsservings)
+  - [`setSpawnArea(populationDefinitionArg, props?)`](#setspawnareapopulationarg-props)
+  - [`setVelocity(velocity)`](#setvelocityvelocity)
+  - [`toBinary(componentVersions)`](#tobinarycomponentversions)
+  - [`toSaveString(options?)`](#tosavestringoptions)
+
+## Types
+
+### `<PrefabProps>`
+
+A configuration object to optionally pass to the `Prefab` constructor. Lets you instantiate a `Prefab` with predefined data. Any properties that you do not pass will be created with a default value.
+
+```ts
+type PrefabProps<TPrefabName extends ATTPrefabName> = {
+  position?: Position | undefined;
+  rotation?: Rotation | undefined;
+  scale?: number | undefined;
+  components?: Partial<PrefabComponents> | undefined;
+  entities?: Partial<PrefabEntities<TPrefabName>> | undefined;
+  children?: PrefabChild[] | undefined;
+};
+```
+
+- `position` (optional) [`<Position>`](../src/types/Position.ts) The world position 3D vector coordinates of the prefab.
+- `rotation` (optional) [`<Rotation>`](../src/types/Rotation.ts) The world rotation quaternion of the prefab.
+- `scale` (optional) `<number>` The scale of the prefab.
+- `components` (optional) `<Partial<`[`PrefabComponents`](../src/types/PrefabComponents.ts)`>>` A mapped object of components on the prefab.
+- `entities` (optional) `<Partial<`[`PrefabEntities`](../src/types/PrefabEntities.ts)`<`[`ATTPrefabName`](./ATTPrefabName.md)`>>>` A mapped object of entities on the prefab.
+- `children` (optional) `<Array<`[`PrefabChild`](../src/types/PrefabChild.ts)`>>` An array of objects connecting child prefabs with parent entities.
+
+## Constructors
+
+### `new Prefab(prefabName, props?)`
+
+Creates a new `Prefab` object configured with the passed in configuration.
+
+- `prefabName` [`<ATTPrefabName>`](./ATTPrefabName.md) The name of the prefab to create.
+- `props` (optional) [`<PrefabProps>`](#prefabprops) Additional configuration of the prefab to create.
+- Returns: `<Prefab>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Wooden_Stake', {
+  position: { x: 133.7, y: 420, z: 69 },
+  rotation: { x: 0.3, y: 0.4, z: 0.1, w: 0.8 },
+  scale: 1.5,
+  components: {
+    NetworkRigidbody: new NetworkRigidbodyComponent({
+      version: 1,
+      position: { x: 133.7, y: 420, z: 69 },
+      rotation: { x: 0.3, y: 0.4, z: 0.1, w: 0.8 },
+      isKinematic: false,
+      isServerSleeping: false,
+      velocity: { x: 0, y: 1, z: 0 },
+      angularVelocity: { x: 0, y: 1, z: 0 }
+    })
+  },
+  entities: {
+    Slot_Multi_11474: new Entity('Slot_Multi_11474')
+  },
+  children: [
+    {
+      parentHash: 11474,
+      prefab: new Prefab('Grass_Clump', {
+        entities: {
+          Fire_30100: new Entity('Fire_30100', {
+            components: {
+              HeatSourceBase: new HeatSourceBaseComponent({
+                version: 2,
+                isLit: true,
+                progress: 0.8
+              })
+            }
+          })
+        }
+      })
+    }
+  ]
+});
+```
+
+---
+
+### `Prefab.fromBinary(reader, componentVersions?)`
+
+Creates a `Prefab` from reading the prefab's binary data stored in a [`<SaveString>`](./SaveString.md).
+
+- `reader` [`<BinaryReader>`](./BinaryReader.md) The binary reader that contains the data stored inside an ATT save string.
+- `componentVersions` (optional) `<Map<number, number>>` A map of component versions to assume are encoded in the binary data.
+- Returns: `<Prefab>`
+
+```ts
+import { BinaryReader, ComponentHash, Prefab, type BinaryString } from 'att-string-transcoder';
+
+const binaryString = `0000000000000000101001001111011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000001111111000000000000000000000000101011010110001000000111011011000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000`;
+
+const reader = new BinaryReader(binaryString as BinaryString);
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 1]
+  // etc...
+]);
+
+const prefab = Prefab.fromBinary<'Handle_Short'>(reader, componentVersions);
+```
+
+---
+
+### `Prefab.fromSaveString(saveString)`
+
+Creates a `Prefab` from reading an ATT save string.
+
+- `saveString` `<string>` The ATT save string to decode into a `Prefab`.
+- Returns: `<Prefab>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const saveString = `43430,230,43430,3290698471,1125743666,1132721897,1050703933,3208373430,1039090831,1058493384,1043542835,2290978823,418,3290698471,1125743666,1132721897,1050703933,3208373430,1039090831,1058493384,3221225472,0,0,0,0,0,363610349,2147483736,3005828291,3221225472,2415919104,0,395228240,397619388,393508864,400941080,2546407302,4157020038,3890602430,1579755829,536870916,374086096,2147483844,1610612736,765,2684354569,338752663,2281701377,0,0,19021736,1744830465,67108864,75722752,0,303,67108864,1124073472,0,0,`;
+
+const prefab = Prefab.fromSaveString<'SpriggullDrumstick_Full_Ripe'>(saveString);
+```
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding an ATT prefab save string.
+
+### `name`
+
+:warning: This property does not occur when decoding an ATT prefab save string but is added by _ATT String Transcoder_ for your convenience when inspecting prefab structures.
+
+- [`<ATTPrefabName>`](./ATTPrefabName.md) The name of the prefab.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+const name = prefab.name;
+// `name` is `'Handle_Short'`
+```
+
+### `hash`
+
+The prefab's hash is a unique numeric identifier for the _type_ of prefab. Every `Handle_Short` in the game will have the same prefab ID. This is not to be confused with a "network ID", which is a unique identifier the game server assigns to each individual object in the game.
+
+- [`<ATTPrefabHash>`](./ATTPrefabHash.md) The hash of the prefab.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+const hash = prefab.hash;
+// `hash` is `42230`
+```
+
+### `position`
+
+:warning: Note that although you can safely read from this public property, you should not modify this property directly. This is because some prefabs also use a [`NetworkRigidbodyComponent`](./NetworkRigidbodyComponent.md) to control their position. You can safely set the position of a prefab using the [`setPosition(position)`](#setpositionposition) method.
+
+- [`<Position>`](../src/types/Position.ts) The position of the prefab.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short', {
+  position: { x: 420, y: 69, z: 1337 }
+});
+
+const position = prefab.position;
+// `position` is `{ x: 420, y: 69, z: 1337 }`
+```
+
+---
+
+### `rotation`
+
+:warning: Note that although you can safely read from this public property, you should not modify this property directly. This is because some prefabs also use a [`NetworkRigidbodyComponent`](./NetworkRigidbodyComponent.md) to control their rotation. You can safely set the rotation of a prefab using the [`setRotation(rotation)`](#setrotationrotation) method.
+
+- [`<Rotation>`](../src/types/Rotation.ts) The rotation of the prefab.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short', {
+  rotation: { x: 0.42, y: -0.69, z: -0.1337, w: 0.88 }
+});
+
+const rotation = prefab.rotation;
+// `rotation` is `{ x: 0.42, y: -0.69, z: -0.1337, w: 0.88 }`
+```
+
+---
+
+### `scale`
+
+Contains the scale of the prefab. You can also set the scale of a prefab using the [`setScale(scale)`](#setscalescale) method.
+
+- `<number>` The scale of the prefab.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short', {
+  scale: 0.69
+});
+
+const scale = prefab.scale;
+// `scale` is approx. `0.69` (within JavaScript floating point precision)
+```
+
+---
+
+### `components`
+
+Provides access to the components stored in this prefab. Components are keyed to their respective names, unless its data contained an unrecognised hash. In that case, the component will be stored in an array under the `Unknown` key.
+
+:bulb: It might be easier to add components using the [`addComponent(component)`](#addcomponentcomponent) method.
+
+- [`<PrefabComponents>`](../src/types/PrefabComponents.ts) A map of the stored components.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short', {
+  components: {
+    NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 })
+  }
+});
+
+const components = prefab.components;
+// `components` is `{
+//   NetworkRigidbody: NetworkRigidbodyComponent {
+//     hash: 2290978823,
+//     name: 'NetworkRigidbody',
+//     position: { x: 0, y: 0, z: 0 },
+//     rotation: { x: 0, y: 0, z: 0, w: 1 },
+//     isKinematic: false,
+//     isServerSleeping: false,
+//     velocity: { x: 0, y: 0, z: 0 },
+//     angularVelocity: { x: 0, y: 0, z: 0 }
+//   },
+//   Unknown: []
+// }`
+```
+
+---
+
+### `entities`
+
+Provides access to the entities stored in this prefab. Entities are keyed to a combination of their respective names and hashes, unless its data contained an unrecognised hash. In that case, the entity will be keyed as `Unknown_` followed by its hash. The reason that entities cannot be keyed without their hashes (like [components](#components)) is because some prefabs have multiple entities with the same name. For example, the `Handle_Fist` prefab has several `Slot_Deco` entities that are only differentiated by their hash. Conversely, it's also possible that an entity exists on different prefabs with the same name but different hashes. For example, the `Fire` entity exists on the `Infinite_Fire` prefab with hash `8488`, but exists on the `Grass_Clump` prefab with hash `30100`. For this reason, _ATT String Transcoder_ uses spawn infodumps from the game to figure out which entities belong to which prefabs and uses this data to provide you with auto-complete options.
+
+:warning: Unfortunately this means that it's not easy to tell upfront which hash a `Fire` entity has on a prefab that you're building. Please ensure that you assign a key that is identical to the entity key (which is name, underscore, and hash).
+
+:bulb: It might be easier to add entities using the [`addEntity(entity)`](#addentityentity) method.
+
+- [`<PrefabEntities<TPrefabName>>`](../src/types/PrefabEntities.ts) A map of the stored entities.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short', {
+  entities: {
+    // Please note the keys include the hash, not just the name.
+    Slot_Multi_6136: new Entity('Slot_Multi_6136'),
+    Slot_Multi_6138: new Entity('Slot_Multi_6138'),
+    Unknown_1337: new Entity('Unknown', { hash: 1337 })
+  }
+});
+
+const entities = prefab.entities;
+// `entities` is `{
+//   Slot_Multi_6136: Entity {
+//     hash: 6136,
+//     name: 'Slot_Multi',
+//     isAlive: true,
+//     components: { Unknown: [] }
+//   },
+//   Slot_Multi_6138: Entity {
+//     hash: 6138,
+//     name: 'Slot_Multi',
+//     isAlive: true,
+//     components: { Unknown: [] }
+//   },
+//   Unknown_1337: Entity {
+//     hash: 1337,
+//     name: 'Unknown',
+//     isAlive: true,
+//     components: { Unknown: [] }
+//   },
+// }`
+```
+
+---
+
+### `children`
+
+Contains an array of objects that map nested prefabs to entities on the current prefab.
+
+:warning: Note that the entity _does not need to exist_ in the prefab in your program! The ATT game server will fill in the blanks. For example, if you create a save string for a `Handle_Short` prefab with several children and no entities on it, and spawn it in-game, it will in fact have all its usual entities to which child prefabs can attach.
+
+:bulb: It might be easier to add child prefabs using the [`addChildPrefab(parentKey, childPrefab)`](#addchildprefabparentkey-childprefab) method.
+
+- [`<PrefabChild[]>`](../src/types/PrefabChild.ts) An array of the stored child prefabs.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short', {
+  children: [
+    {
+      // Please note the entity hash below wasn't defined elsewhere in this prefab, yet this will work when spawned in-game.
+      parentHash: 6136, // The hash for `Slot_Multi_6136` on `Handle_Short` prefab.
+      prefab: new Prefab('Guard')
+    }
+  ]
+});
+
+const children = prefab.children;
+// `children` is `[
+//   {
+//     parentHash: 6136,
+//     prefab: Prefab {
+//       name: 'Guard',
+//       hash: 51672,
+//       position: { x: 0, y: 0, z: 0 },
+//       rotation: { x: 0, y: 0, z: 0, w: 1 }
+//       scale: 1,
+//       components: { Unknown: [] },
+//       entities: {},
+//       children: []
+//     }
+//   }
+// ]`
+```
+
+## Methods
+
+### `addChildPrefab(parentKey, childPrefab)`
+
+Attaches a `Prefab` to this prefab as a child. It can optionally be attached onto one of this prefab's embedded entities, which is required for most child prefabs under normal circumstances. If you do not specify a `parentKey`, you may pass `null` to create a "floating" child. It will be part of this prefab's hierarchy but will most likely behave unexpectedly in the game.
+
+- `parentKey` `<Exclude<`[`EntityKey<ATTPrefabName>`](../src/types/EntityKey.ts)`, 'Unknown'> | null>` The key of the prefab's entity to which you want to attach the `childPrefab`.
+- `childPrefab` `<Prefab>` The prefab you want to attach as a child.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const parent = new Prefab('Handle_Short');
+const child = new Prefab('Guard');
+
+parent.addChildPrefab('Slot_Large_SwordType_Craft_54356', child);
+```
+
+---
+
+### `addComponent(component)`
+
+Adds a `Component` to the prefab. Will override any existing component with that name.
+
+- `component` [`<Component>`](./Component.md) The component to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { NetworkRigidbodyComponent, Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+const component = new NetworkRigidbodyComponent({ version: 1 });
+
+prefab.addComponent(component);
+```
+
+---
+
+### `addEntity(entity)`
+
+Adds an `Entity` to the prefab. Will override any existing entity with that key.
+
+- `entity` [`<Entity>`](./Entity.md) The entity to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { Entity, Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+const entity = new Entity<'Handle_Short'>('Slot_Multi_6136');
+
+prefab.addEntity(entity);
+```
+
+---
+
+### `addGift(giftPrefab)`
+
+Adds a `Prefab` gift to this prefab's [`SentGift`](./SentGiftComponent.md) component. You may call this method more than once to add additional gifts.
+
+- `giftPrefab` `<Prefab>` The prefab you want to store inside the gift box.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const box = new Prefab('Gift_Mail_Box');
+const gift = new Prefab('Dynamite');
+
+box.addGift(gift);
+```
+
+---
+
+### `clone(options?)`
+
+Returns a deep clone of the prefab.
+
+- `options` (optional, default `{}`) See [`toSaveString(options?)`](#tosavestringoptions).
+- Returns: `<Prefab>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const original = new Prefab('Guard').setMaterial('Mythril');
+const clone = original.clone();
+
+clone.setMaterial('Gold');
+
+const originalMaterial = original.getMaterial();
+// `originalMaterial` is still `31174` (Mythril)
+
+const cloneMaterial = clone.getMaterial();
+// `cloneMaterial` is `56394` (Gold)
+```
+
+---
+
+### `getAngularVelocity()`
+
+Gets the spin (vector) on the prefab.
+
+- Returns: [`<AngularVelocity>`](../src/types/AngularVelocity.ts)
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Stone'>.fromSaveString('...');
+
+const angularVelocity = prefab.getAngularVelocity();
+const { x, y, z } = angularVelocity;
+```
+
+---
+
+### `getChildPrefab(prefabName, parentHash?)`
+
+Finds the first child prefab matching the given name. If there are multiple child prefabs with the same name, you can use the second argument to provide a parent hash to match against.
+
+- `prefabName` [`<ATTPrefabName>`](./ATTPrefabName.md) The name of the child prefab to get.
+- `parentHash` (optional) `<number>` The entity hash of the child prefab. Useful when differentiating between multiple children with the same name.
+- Returns: `<Prefab | undefined>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+prefab.addChildPrefab('Slot_Large_SwordType_Craft_6134', new Prefab('Guard'));
+
+const childGuard = prefab.getChildPrefab('Guard');
+// `childGuard` is an instance of `Prefab<'Guard'>`
+
+const childPommel = prefab.getChildPrefab('Pommel');
+// `childPommel` is `undefined`
+```
+
+---
+
+### `getComponentVersions()`
+
+Gets a map of component hashes and the versions used on this prefab. Will throw an error if the prefab uses mixed versions of a particular component.
+
+- Returns: `Map<number, number>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const componentVersions = prefab.getComponentVersions();
+```
+
+---
+
+### `getGiftBoxLabel()`
+
+Gets the gift sender's name, which is labeled on the gift.
+
+- Returns: `<string>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Gift_Mail_Box'>.fromSaveString('...');
+
+const giftBoxLabel = prefab.getGiftBoxLabel();
+```
+
+---
+
+### `getIntegrity()`
+
+Gets the prefab's physical integrity.
+
+- Returns: `<number>` between `0` and `1`.
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const integrity = prefab.getIntegrity();
+```
+
+---
+
+### `getKinematic()`
+
+Gets the [kinematic](https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html) state of the prefab.
+
+- Returns: `<boolean>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const isKinematic = prefab.getKinematic();
+```
+
+---
+
+### `getMaterial()`
+
+Gets the prefab's physical material.
+
+- Returns: [`<PhysicalMaterialPartHash>`](../src/types/PhysicalMaterialPartHash.ts)
+
+```ts
+import { PhysicalMaterialPartHash, Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Guard'>.fromSaveString('...');
+
+const materialHash = prefab.getMaterial();
+const materialName = PhysicalMaterialPartHash[materialHash];
+```
+
+---
+
+### `getOnFire()`
+
+Gets the burning state of the prefab.
+
+- Returns: `<boolean>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Grass_Clump'>.fromSaveString('...');
+
+const isOnFire = prefab.getOnFire();
+```
+
+---
+
+### `getPosition()`
+
+Gets the position of the prefab. If the prefab is a child of another prefab, then this position is local to that parent. Otherwise, this position is in world space.
+
+- Returns: [`<Position>`](../src/types/Position.ts)
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const position = prefab.getPosition();
+const { x, y, z } = position;
+```
+
+---
+
+### `getRotation()`
+
+Gets the rotation of the prefab. If the prefab is a child of another prefab, then this rotation is local to that parent. Otherwise, this rotation is in world space.
+
+- Returns: [`<Rotation>`](../src/types/Rotation.ts)
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const rotation = prefab.getRotation();
+const { x, y, z, w } = rotation;
+```
+
+---
+
+### `getScale()`
+
+Gets the scale of the prefab.
+
+- Returns: `<number>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const scale = prefab.getScale();
+```
+
+---
+
+### `getServerSleeping()`
+
+Gets the [sleeping](https://docs.unity3d.com/Manual/RigidbodiesOverview.html) state of the prefab.
+
+- Returns: `<boolean>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+const isServerSleeping = prefab.getServerSleeping();
+```
+
+---
+
+### `getServings()`
+
+Gets the number of servings on a liquid container prefab.
+
+- Returns: `<number>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Potion_Medium'>.fromSaveString('...');
+
+const servings = prefab.getServings();
+```
+
+---
+
+### `getSpawnAreaPopulationName()`
+
+Gets the name of the spawn area population, if there is one. Returns `undefined` otherwise.
+
+- Returns: `<'Unknown' | `[`PopulationDefinitionName`](../src/types/PopulationDefinitionName.ts)` | undefined>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Disk_Encounter'>.fromSaveString('...');
+
+const populationName = prefab.getSpawnAreaPopulationName();
+```
+
+---
+
+### `getVelocity()`
+
+Gets the direction (vector) on the prefab. Units are in metres per second.
+
+- Returns: [`<Velocity>`](../src/types/Velocity.ts)
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Stone'>.fromSaveString('...');
+
+const velocity = prefab.getVelocity();
+const { x, y, z } = velocity;
+```
+
+---
+
+### `inspect()`
+
+Prints this prefab's data structure to the console.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.inspect();
+```
+
+---
+
+### `print()`
+
+Prints this prefab's save string to the console.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.print();
+```
+
+---
+
+### `removeAllChildPrefabs()`
+
+Removes all child `Prefab` from this prefab.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.removeAllChildPrefabs();
+```
+
+---
+
+### `removeAllComponents()`
+
+Removes all components on this prefab.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.removeAllComponents();
+```
+
+---
+
+### `removeAllEntities()`
+
+Removes all entities on this prefab.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.removeAllEntities();
+```
+
+---
+
+### `removeAllGifts()`
+
+Removes all gift `Prefab` from this prefab.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Gift_Mail_Box'>.fromSaveString('...');
+
+prefab.removeAllGifts();
+```
+
+---
+
+### `removeChildPrefab(prefabArg)`
+
+Removes the specified child `Prefab` from this prefab.
+
+- `prefabArg` `<`[`ATTPrefabHash`](./ATTPrefabHash.md)`|`[`ATTPrefabName`](./ATTPrefabName.md)`>` The child prefab's hash or name to remove from this prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.removeChildPrefab(51672);
+// or
+prefab.removeChildPrefab('Guard');
+```
+
+---
+
+### `removeComponent(componentArg)`
+
+Removes the specified component from this prefab.
+
+- `componentArg` `<`[`ComponentHash`](../src/types/ComponentHash.ts)` | keyof Omit<`[`PrefabComponents`](../src/types/PrefabComponents.ts)`, 'Unknown'>>` The component's hash or name to remove from this prefab.
+- Returns: `<this>`
+
+```ts
+import { ComponentHash, Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.removeComponent(ComponentHash.NetworkRigidbody);
+// or
+prefab.removeComponent('NetworkRigidbody');
+```
+
+---
+
+### `removeEntity(entityKey)`
+
+Removes the specified entity from this prefab.
+
+- `entityKey` `<Exclude<`[`EntityKey`](../src/types/EntityKey.ts)`<`[`ATTPrefabName`](./ATTPrefabName.md)`>>>` The entity's key to remove from this prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+
+prefab.removeEntity('Slot_Multi_6136');
+```
+
+---
+
+### `removeGift(prefabArg)`
+
+Removes the specified gift `Prefab` from this prefab.
+
+- `prefabArg` `<`[`ATTPrefabHash`](./ATTPrefabHash.md)`|`[`ATTPrefabName`](./ATTPrefabName.md)>` The gift prefab's hash or name to remove from this prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Gift_Mail_Box'>.fromSaveString('...');
+
+prefab.removeGift(31326);
+// or
+prefab.removeGift('Dynamite');
+```
+
+---
+
+### `removeSpawnArea()`
+
+Removes the spawn area components from this prefab.
+
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = Prefab<'Disk_Encounter'>.fromSaveString('...');
+
+prefab.removeSpawnArea();
+```
+
+---
+
+### `setAngularVelocity(angularVelocity)`
+
+Sets a spin (vector) on the prefab, causing the physics engine to apply a force to it when spawning. Units are in metres per second. Only works reliably on the parent prefab. Does not work on kinematic prefabs. Does not work on static prefabs.
+
+- `angularVelocity` [`<AngularVelocity>`](../src/types/AngularVelocity.ts) The angular velocity to set on this prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+prefab.setAngularVelocity({ x: 420, y: 69, z: 1337 });
+```
+
+---
+
+### `setGiftBoxLabel(label)`
+
+Sets the gift sender's name, which is labeled on the gift.
+
+- `label` `<string>` The label to set on the gift box.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Gift_Mail_Box');
+
+prefab.setGiftBoxLabel('topkek');
+```
+
+---
+
+### `setIntegrity(integrity)`
+
+Sets the prefab's integrity. This can change both its appearance and other qualities such as durability and the amount of materials recovered from recycling.
+
+- `integrity` `<number>` The integrity of the physical material of the prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+prefab.setIntegrity(0.69);
+```
+
+---
+
+### `setKinematic(isKinematic?)`
+
+Makes the prefab [kinematic](https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html). By default, a `new Prefab()` is not kinematic, but some prefabs require to be kinematic to work properly. You can optionally pass a boolean, for example `setKinematic(false)`.
+
+- `isKinematic` (optional, default `true`) `<boolean>` Whether the prefab must be kinematic or not.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+prefab.setKinematic(true);
+```
+
+---
+
+### `setMaterial(materialArg)`
+
+Sets the prefab's physical material. This can change both its appearance and other qualities such as durability, damage, heat retention and weight.
+
+- `materialArg` [`<PhysicalMaterialPartHash | keyof typeof PhysicalMaterialPartHash>`](../src/types/PhysicalMaterialPartHash.ts) The physical material's hash or name to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { PhysicalMaterialPartHash, Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+prefab.setMaterial(PhysicalMaterialPartHash.Mythril);
+// or
+prefab.setMaterial('Mythril');
+```
+
+---
+
+### `setOnFire(isLit?)`
+
+Sets the prefab on fire, if it is capable of catching fire.
+
+- `isLit` (optional, default `true`) `<boolean>` Whether or not to set the prefab alight.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Grass_Clump');
+
+prefab.setOnFire(true);
+```
+
+---
+
+### `setPosition(position)`
+
+Sets the position of the prefab. If the prefab is a child of another prefab, then this position is local to that parent. Otherwise, this position is in world space.
+
+- `position` [`<Position>`](../src/types/Position.ts) The position to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+prefab.setPosition({ x: 420, y: 69, z: 1337 });
+```
+
+---
+
+### `setRotation(rotation)`
+
+Sets the rotation of the prefab. If the prefab is a child of another prefab, then this rotation is local to that parent. Otherwise, this rotation is in world space.
+
+- `rotation` [`<Rotation>`](../src/types/Rotation.ts) The rotation to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+prefab.setRotation({ x: 0.42, y: -0.69, z: 0.1337, w: -0.88 });
+```
+
+---
+
+### `setScale(scale)`
+
+Sets the scale of the prefab.
+
+- `scale` `<number>` The scale to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+prefab.setScale(0.69);
+```
+
+---
+
+### `setServerSleeping(isServerSleeping?)`
+
+Makes the prefab [sleep](https://docs.unity3d.com/Manual/RigidbodiesOverview.html). By default, a `new Prefab()` is not sleeping. A sleeping prefab does not have its physics simulated until it receives a collision or force, such as touching it. You can optionally pass a boolean, for example `setServerSleeping(false)`.
+
+- `isServerSleeping` (optional, default `true`) `<boolean>` Whether the prefab must be sleeping or not.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Handle_Short');
+
+prefab.setServerSleeping(true);
+```
+
+---
+
+### `setServings(servings)`
+
+Sets the number of servings on a liquid container prefab.
+
+- `servings` `<number>` The amount of servings to set on the prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Potion_Medium');
+
+prefab.setServings(69);
+```
+
+---
+
+### `setSpawnArea(populationArg, props?)`
+
+Sets a spawn area on the prefab with the given population and any additional configuration.
+
+- `populationArg` `<`[`PopulationDefinitionHash`](../src/types/PopulationDefinitionHash.ts)`|`[`PopulationDefinitionName`](../src/types/PopulationDefinitionName.ts)`>` The spawn area population hash or name to set on the prefab.
+- `props` (optional, default `{}`) [`<SetSpawnAreaProps>`](../src/types/SetSpawnAreaProps.ts) Additional properties for configuring the spawn area.
+- Returns: `<this>`
+
+```ts
+import { PopulationDefinitionHash, Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Disk_Encounter');
+
+prefab.setSpawnArea(PopulationDefinitionHash.WyrmPopulation, {
+  currentPopulation: 5,
+  isOneOff: false,
+  isPopulationStarted: true,
+  maxPopulation: 20,
+  numberOfSpawnPoints: 40,
+  size: 5,
+  startingPopulation: 5
+});
+```
+
+---
+
+### `setVelocity(velocity)`
+
+Sets a direction (vector) on the prefab, causing the physics engine to apply a force to it when spawning. Units are in metres per second. Only works reliably on the parent prefab. Does not work on kinematic prefabs. Does not work on static prefabs.
+
+- `velocity` [`<Velocity>`](../src/types/Velocity.ts) The velocity to set on this prefab.
+- Returns: `<this>`
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+prefab.setVelocity({ x: 420, y: 69, z: 1337 });
+```
+
+---
+
+### `toBinary(componentVersions)`
+
+Returns a `BinaryString` representation of the prefab.
+
+- `componentVersions` `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: [`<BinaryString>`](./BinaryString.md)
+
+```ts
+import { ComponentHash, Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+const componentVersions = prefab.getComponentVersions();
+// or
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+const binaryString = prefab.toBinary(componentVersions);
+```
+
+---
+
+### `toSaveString(options?)`
+
+Returns the `SaveString` to spawn this prefab in the game. You may pass additional options to change the output behaviour.
+
+- `options` (optional, default `{}`) `<ToSaveStringOptions>`
+- `options.excludeComponentVersions` (optional, default `false`) Set to true to force a save string without component versions.
+- `options.ignoreIndeterminateComponentVersions` (optional, default `false`) Same as `excludeComponentVersions` but only when encountering indeterminate component versions.
+- Returns: [`<SaveString>`](./SaveString.md)
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const prefab = new Prefab('Stone');
+
+const saveString = prefab.toSaveString();
+```
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..1911d10
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,58 @@
+# API Reference Documentation
+
+- Types
+  - [`<ATTPrefabHash>`](./ATTPrefabHash.md)
+  - [`<ATTPrefabName>`](./ATTPrefabName.md)
+  - [`<BinaryString>`](./BinaryString.md)
+  - [`<SaveString>`](./SaveString.md)
+- Classes
+  - [`BasicDecayComponent`](./BasicDecayComponent.md)
+  - [`BinaryData`](./BinaryData.md)
+  - [`BinaryReader`](./BinaryReader.md)
+  - [`BinaryWriter`](./BinaryWriter.md)
+  - [`Component`](./Component.md)
+  - [`DoorComponent`](./DoorComponent.md)
+  - [`DurabilityModuleComponent`](./DurabilityModuleComponent.md)
+  - [`Entity`](./Entity.md)
+  - [`FireComponent`](./FireComponent.md)
+  - [`FuseComponent`](./FuseComponent.md)
+  - [`HeatSourceBaseComponent`](./HeatSourceBaseComponent.md)
+  - [`LiquidContainerComponent`](./LiquidContainerComponent.md)
+  - [`LogicBoolReceiverComponent`](./LogicBoolReceiverComponent.md)
+  - [`LogicBoolSenderComponent`](./LogicBoolSenderComponent.md)
+  - [`LogicFloatReceiverComponent`](./LogicFloatReceiverComponent.md)
+  - [`LogicFloatSenderComponent`](./LogicFloatSenderComponent.md)
+  - [`LogicGateReceiverComponent`](./LogicGateReceiverComponent.md)
+  - [`LogicIntReceiverComponent`](./LogicIntReceiverComponent.md)
+  - [`LogicIntSenderComponent`](./LogicIntSenderComponent.md)
+  - [`LogicVector3ReceiverComponent`](./LogicVector3ReceiverComponent.md)
+  - [`LogicVector3SenderComponent`](./LogicVector3SenderComponent.md)
+  - [`NetworkRigidbodyComponent`](./NetworkRigidbodyComponent.md)
+  - [`PhysicalMaterialPartComponent`](./PhysicalMaterialPartComponent.md)
+  - [`PickupComponent`](./PickupComponent.md)
+  - [`PickupDockComponent`](./PickupDockComponent.md)
+  - [`PopulationSpawnAreaComponent`](./PopulationSpawnAreaComponent.md)
+  - [`Prefab`](./Prefab.md)
+  - [`SentGiftComponent`](./SentGiftComponent.md)
+  - [`SlidingDoorComponent`](./SlidingDoorComponent.md)
+  - [`SpawnAreaComponent`](./SpawnAreaComponent.md)
+  - [`StatManagerComponent`](./StatManagerComponent.md)
+  - [`UnsupportedComponent`](./UnsupportedComponent.md)
+  - [`WoodcutTreeComponent`](./WoodcutTreeComponent.md)
+- Functions
+  - [`isATTPrefabHash(hash)`](./isATTPrefabHash.md)
+  - [`isATTPrefabName(name)`](./isATTPrefabName.md)
+  - [`isSavableComponent(componentName, prefabArg)`](./isSavableComponent.md)
+  - [`isUnknownComponent(component)`](./isUnknownComponent.md)
+  - [`readChildren(reader, componentVersions?)`](./readChildren.md)
+  - [`readComponent(reader, hash, name, version)`](./readComponent.md)
+  - [`readComponents(reader, versions?)`](./readComponents.md)
+  - [`readEntities(reader, prefabName, componentVersions?)`](./readEntities.md)
+  - [`writeChildren(writer, children, componentVersions)`](./writeChildren.md)
+  - [`writeComponents(writer, components, versions)`](./writeComponents.md)
+  - [`writeEntities(writer, entities, componentVersions)`](./writeEntities.md)
+- Examples
+  - [Alter a sword's material](./examples/Alter-a-swords-material.md)
+  - [Flask of infinite teleportation](./examples/Flask-of-infinite-teleportation.md)
+  - [Integrate with a bot](./examples/Integrate-with-a-bot.md)
+  - [Launch a wyrm spit](./examples/Launch-a-wyrm-spit.md)
diff --git a/docs/SaveString.md b/docs/SaveString.md
new file mode 100644
index 0000000..2a050b1
--- /dev/null
+++ b/docs/SaveString.md
@@ -0,0 +1,5 @@
+# `<SaveString>`
+
+The `<SaveString>` type is used to narrow `<string>` types to recognised ATT save strings.
+
+You can use the [`BinaryData.isSaveString`](./BinaryData.md#binarydataissavestring) type assertion function to narrow down your `<string>` types.
diff --git a/docs/SentGiftComponent.md b/docs/SentGiftComponent.md
new file mode 100644
index 0000000..955287d
--- /dev/null
+++ b/docs/SentGiftComponent.md
@@ -0,0 +1,189 @@
+# Class: `SentGiftComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<SentGiftComponentProps>`](#sentgiftcomponentprops)
+- [Constructors](#constructors)
+  - [`new SentGiftComponent(props)`](#new-sentgiftcomponentprops)
+  - [`SentGiftComponent.fromBinary(reader, version)`](#sentgiftcomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`receiverName`](#receivername)
+  - [`senderName`](#sendername)
+  - [`gifts`](#gifts)
+  - [`senderTag`](#sendertag)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<SentGiftComponentProps>`
+
+A portion of the configuration object to pass to the `SentGiftComponent` constructor.
+
+```ts
+type Gift = null | {
+  data: number[];
+  messageSizeInBytes: number;
+  hash: number;
+  chunkVersioning: number[];
+};
+
+type SentGiftTag = null | {
+  from: number;
+  to: number;
+};
+
+type SentGiftComponentPropsV1 = {
+  receiverName?: string | undefined;
+  senderName?: string | undefined;
+  gifts?: Gift[] | undefined;
+  senderTag?: SentGiftTag | undefined;
+};
+
+type SentGiftComponentProps = SentGiftComponentPropsV1;
+```
+
+#### Since v1
+
+- `receiverName` (optional, default `''`) `<string>`
+- `senderName` (optional, default `''`) `<string>`
+- `gifts` (optional, default `[]`) `<Array<Gift>>`
+- `senderTag` (optional, default `null`) `<SentGiftTag>`
+
+## Constructors
+
+### `new SentGiftComponent(props)`
+
+Creates a versioned `SentGift` component.
+
+- `props` [`<ComponentProps & SentGiftComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<SentGiftComponent>`
+
+```ts
+import { SentGiftComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SentGiftComponent({ version: componentVersion });
+```
+
+---
+
+### `SentGiftComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `receiverName`
+
+Name of the player intended as the receiver of the prefab this component is attached to.
+
+- Since: `v1`
+- `<string>`
+
+```ts
+import { SentGiftComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SentGiftComponent({ version: componentVersion });
+
+const receiverName = component.receiverName;
+// `receiverName` is `''`
+```
+
+---
+
+### `senderName`
+
+Name of the player intended as the sender of the prefab this component is attached to. This name will be displayed as a label on a gift box prefab.
+
+- Since: `v1`
+- `<string>`
+
+```ts
+import { SentGiftComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SentGiftComponent({ version: componentVersion });
+
+const senderName = component.senderName;
+// `senderName` is `''`
+```
+
+---
+
+### `gifts`
+
+Array of gifts, which are prefab save strings.
+
+- Since: `v1`
+- `<Array<Gift>>`
+
+```ts
+import { SentGiftComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SentGiftComponent({ version: componentVersion });
+
+const gifts = component.gifts;
+// `gifts` is `[]`
+```
+
+---
+
+### `senderTag`
+
+- Since: `v3`
+- `<SentGiftTag>`
+
+```ts
+import { SentGiftComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SentGiftComponent({ version: componentVersion });
+
+const senderTag = component.senderTag;
+// `senderTag` is `null`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/SlidingDoorComponent.md b/docs/SlidingDoorComponent.md
new file mode 100644
index 0000000..8d27a9d
--- /dev/null
+++ b/docs/SlidingDoorComponent.md
@@ -0,0 +1,113 @@
+# Class: `SlidingDoorComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<SlidingDoorComponentProps>`](#slidingdoorcomponentprops)
+- [Constructors](#constructors)
+  - [`new SlidingDoorComponent(props)`](#new-slidingdoorcomponentprops)
+  - [`SlidingDoorComponent.fromBinary(reader, version)`](#slidingdoorcomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`isOpen`](#isopen)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<SlidingDoorComponentProps>`
+
+A portion of the configuration object to pass to the `SlidingDoorComponent` constructor.
+
+```ts
+type SlidingDoorComponentPropsV1 = {
+  isOpen?: number | undefined;
+};
+
+type SlidingDoorComponentProps = SlidingDoorComponentPropsV1;
+```
+
+#### Since v1
+
+- `isOpen` (optional, default `false`) `<boolean>`
+
+## Constructors
+
+### `new SlidingDoorComponent(props)`
+
+Creates a versioned `SlidingDoor` component.
+
+- `props` [`<ComponentProps & SlidingDoorComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<SlidingDoorComponent>`
+
+```ts
+import { SlidingDoorComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SlidingDoorComponent({ version: componentVersion });
+```
+
+---
+
+### `SlidingDoorComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `isOpen`
+
+Reveals the open state of this component's prefab
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { SlidingDoorComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SlidingDoorComponent({ version: componentVersion });
+
+const isOpen = component.isOpen;
+// `isOpen` is `false`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/SpawnAreaComponent.md b/docs/SpawnAreaComponent.md
new file mode 100644
index 0000000..fc1e0ff
--- /dev/null
+++ b/docs/SpawnAreaComponent.md
@@ -0,0 +1,193 @@
+# Class: `SpawnAreaComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<SpawnAreaComponentProps>`](#spawnareacomponentprops)
+- [Constructors](#constructors)
+  - [`new SpawnAreaComponent(props)`](#new-spawnareacomponentprops)
+  - [`SpawnAreaComponent.fromBinary(reader, version)`](#spawnareacomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`size`](#size)
+  - [`groundLayers`](#groundlayers)
+  - [`avoidLayers`](#avoidlayers)
+  - [`isAligningNormal`](#isaligningnormal)
+  - [`maxAcceptableAngleDot`](#maxacceptableangledot)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<SpawnAreaComponentProps>`
+
+A portion of the configuration object to pass to the `SpawnAreaComponent` constructor.
+
+```ts
+type SpawnAreaComponentPropsV1 = {
+  size?: number | undefined;
+  groundLayers?: number | undefined;
+  avoidLayers?: number | undefined;
+  isAligningNormal?: boolean | undefined;
+  maxAcceptableAngleDot?: number | undefined;
+};
+
+type SpawnAreaComponentProps = SpawnAreaComponentPropsV1;
+```
+
+#### Since v1
+
+- `size` (optional, default `5`) `<number>`
+- `groundLayers` (optional, default `1280`) `<number>`
+- `avoidLayers` (optional, default `8721`) `<number>`
+- `isAligningNormal` (optional, default `false`) `<boolean>`
+- `maxAcceptableAngleDot` (optional, default `-1`) `<number>`
+
+## Constructors
+
+### `new SpawnAreaComponent(props)`
+
+Creates a versioned `SpawnArea` component.
+
+- `props` [`<ComponentProps & SpawnAreaComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<SpawnAreaComponent>`
+
+```ts
+import { SpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SpawnAreaComponent({ version: componentVersion });
+```
+
+---
+
+### `SpawnAreaComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `size`
+
+The size (in metres) of the spawn area of the prefab this component is attached to.
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { SpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SpawnAreaComponent({ version: componentVersion });
+
+const size = component.size;
+// `size` is `5`
+```
+
+---
+
+### `groundLayers`
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { SpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SpawnAreaComponent({ version: componentVersion });
+
+const groundLayers = component.groundLayers;
+// `groundLayers` is `1280`
+```
+
+---
+
+### `avoidLayers`
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { SpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SpawnAreaComponent({ version: componentVersion });
+
+const avoidLayers = component.avoidLayers;
+// `avoidLayers` is `8721`
+```
+
+---
+
+### `isAligningNormal`
+
+- Since: `v1`
+- `<boolean>`
+
+```ts
+import { SpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SpawnAreaComponent({ version: componentVersion });
+
+const isAligningNormal = component.isAligningNormal;
+// `isAligningNormal` is `false`
+```
+
+---
+
+### `maxAcceptableAngleDot`
+
+- Since: `v1`
+- `<number>`
+
+```ts
+import { SpawnAreaComponent } from 'att-string-transcoder';
+
+const componentVersion = 1;
+const component = new SpawnAreaComponent({ version: componentVersion });
+
+const maxAcceptableAngleDot = component.maxAcceptableAngleDot;
+// `maxAcceptableAngleDot` is `-1`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/StatManagerComponent.md b/docs/StatManagerComponent.md
new file mode 100644
index 0000000..53ca317
--- /dev/null
+++ b/docs/StatManagerComponent.md
@@ -0,0 +1,176 @@
+# Class: `StatManagerComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<StatManagerComponentProps>`](#statmanagercomponentprops)
+- [Constructors](#constructors)
+  - [`new StatManagerComponent(props)`](#new-statmanagercomponentprops)
+  - [`StatManagerComponent.fromBinary(reader, version)`](#statmanagercomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`stats`](#stats)
+  - [`modifiers`](#modifiers)
+  - [`indirectStatModifiers`](#indirectstatmodifiers)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<StatManagerComponentProps>`
+
+A portion of the configuration object to pass to the `StatManagerComponent` constructor.
+
+```ts
+type Stat = null | {
+  hash: number;
+  baseFlat: number;
+};
+
+type TimedModifier = null | {
+  hash: number;
+  value: number;
+  isMultiplier: boolean;
+  time: number;
+};
+
+type IndirectModifierSaveData = {
+  valueOverDurationHash: number;
+  baseValue: number;
+  duration: number;
+  tick: number;
+};
+
+type IndirectStatModifier = null | {
+  hash: number;
+  time: number;
+  modifiers: IndirectModifierSaveData[];
+};
+
+type StatManagerComponentPropsV2 = {
+  stats?: Stat[] | undefined;
+  modifiers?: TimedModifier[] | undefined;
+  indirectStatModifiers?: IndirectStatModifier[] | undefined;
+};
+
+type StatManagerComponentProps = StatManagerComponentPropsV2;
+```
+
+#### Since v2
+
+- `stats` (optional, default `[]`) `<Array<Stat>>`
+- `modifiers` (optional, default `[]`) `<Array<TimedModifier>>`
+- `indirectStatModifiers` (optional, default `[]`) `<Array<IndirectStatModifier>>`
+
+## Constructors
+
+### `new StatManagerComponent(props)`
+
+Creates a versioned `StatManager` component.
+
+- `props` [`<ComponentProps & StatManagerComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<StatManagerComponent>`
+
+```ts
+import { StatManagerComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new StatManagerComponent({ version: componentVersion });
+```
+
+---
+
+### `StatManagerComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `stats`
+
+- Since: `v2`
+- `<Array<Stat>>`
+
+```ts
+import { StatManagerComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new StatManagerComponent({ version: componentVersion });
+
+const stats = component.stats;
+// `stats` is `[]`
+```
+
+---
+
+### `modifiers`
+
+- Since: `v2`
+- `<Array<TimedModifier>>`
+
+```ts
+import { StatManagerComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new StatManagerComponent({ version: componentVersion });
+
+const modifiers = component.modifiers;
+// `modifiers` is `[]`
+```
+
+---
+
+### `indirectStatModifiers`
+
+- Since: `v2`
+- `<Array<IndirectStatModifier>>`
+
+```ts
+import { StatManagerComponent } from 'att-string-transcoder';
+
+const componentVersion = 2;
+const component = new StatManagerComponent({ version: componentVersion });
+
+const indirectStatModifiers = component.indirectStatModifiers;
+// `indirectStatModifiers` is `[]`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/UnsupportedComponent.md b/docs/UnsupportedComponent.md
new file mode 100644
index 0000000..fadafb4
--- /dev/null
+++ b/docs/UnsupportedComponent.md
@@ -0,0 +1,144 @@
+# Class: `UnsupportedComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<UnsupportedComponentProps>`](#unsupportedcomponentprops)
+- [Constructors](#constructors)
+  - [`new UnsupportedComponent(props)`](#new-unsupportedcomponentprops)
+  - [`UnsupportedComponent.fromBinary(reader, version, hash, name, dataLength)`](#unsupportedcomponentfrombinaryreader-version-hash-name-datalength)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`rawData`](#rawdata)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<UnsupportedComponentProps>`
+
+A portion of the configuration object to pass to the `UnsupportedComponent` constructor.
+
+```ts
+type UnsupportedComponentProps = {
+  hash: number;
+  name: string;
+  rawData: BinaryString;
+};
+```
+
+- `hash` `<number>` The hash of the component.
+- `name` `<string>` The name of the component.
+- `rawData` [`<BinaryString>`](./BinaryString.md) The serialised data of the component.
+
+## Constructors
+
+### `new UnsupportedComponent(props)`
+
+Creates a versioned component without deserialising its data.
+
+- `props` [`<ComponentProps & UnsupportedComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<UnsupportedComponent>`
+
+```ts
+import { UnsupportedComponent } from 'att-string-transcoder';
+
+const hash = 1337;
+const name = 'SomeUnrecognisedComponentName';
+const rawData = '11110111001100010000';
+const version = 1;
+
+const component = new UnsupportedComponent({ hash, name, rawData, version });
+```
+
+---
+
+### `UnsupportedComponent.fromBinary(reader, version, hash, name, dataLength)`
+
+Reads the binary string data and returns an instantiated component.
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` instance containing the entity binary data.
+- `version` `<number>` The version of the component for interpreting the binary data.
+- `hash` `<number>` The hash of the component.
+- `name` `<string>` The name of the component.
+- `dataLength` `<number>` The length of the component's binary data.
+
+```ts
+import { BinaryReader, UnsupportedComponent } from 'att-string-transcoder';
+
+const reader = new BinaryReader('...');
+const componentVersion = 1;
+const componentHash = 1337;
+const componentName = 'SomeUnrecognisedComponentName';
+const componentDataLength = 20;
+
+const component = UnsupportedComponent.fromBinary(
+  reader,
+  componentVersion,
+  componentHash,
+  componentName,
+  componentDataLength
+);
+```
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `rawData`
+
+The component's serialised data.
+
+- [`<BinaryString>`](./BinaryString.md) The component's serialised data.
+
+```ts
+import { UnsupportedComponent } from 'att-string-transcoder';
+
+const hash = 1337;
+const name = 'SomeUnrecognisedComponentName';
+const rawData = '11110111001100010000';
+const version = 1;
+
+const component = new UnsupportedComponent({ hash, name, rawData, version });
+
+const rawData = component.rawData;
+// `rawData` is `'11110111001100010000'`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/WoodcutTreeComponent.md b/docs/WoodcutTreeComponent.md
new file mode 100644
index 0000000..f847347
--- /dev/null
+++ b/docs/WoodcutTreeComponent.md
@@ -0,0 +1,133 @@
+# Class: `WoodcutTreeComponent`
+
+- [Types](#types)
+  - [`<ComponentProps>`](#componentprops)
+  - [`<WoodcutTreeComponentProps>`](#basicdecaycomponentprops)
+- [Constructors](#constructors)
+  - [`new WoodcutTreeComponent(props)`](#new-basicdecaycomponentprops)
+  - [`WoodcutTreeComponent.fromBinary(reader, version)`](#basicdecaycomponentfrombinaryreader-version)
+- [Properties](#properties)
+  - [`hash`](#hash)
+  - [`name`](#name)
+  - [`version`](#version)
+  - [`presetHash`](#presethash)
+  - [`speciesHash`](#specieshash)
+- [Methods](#methods)
+  - [`toBinary(version?)`](#tobinaryversion)
+  - [`write(writer, version?)`](#writewriter-version)
+
+## Types
+
+### `<ComponentProps>`
+
+See [`<ComponentProps>`](./Component.md#componentprops)
+
+---
+
+### `<WoodcutTreeComponentProps>`
+
+A portion of the configuration object to pass to the `WoodcutTreeComponent` constructor.
+
+```ts
+type WoodcutTreeComponentPropsV3 = {
+  presetHash?: 0 | PresetHash | undefined;
+  speciesHash?: SpeciesHash | undefined;
+};
+
+type WoodcutTreeComponentProps = WoodcutTreeComponentPropsV3;
+```
+
+#### Since v3
+
+- `presetHash` (optional, default `0`) `<number>`
+- `speciesHash` (optional, default `11232`) [`<SpeciesHash>`](../src/types/SpeciesHash.ts)
+
+## Constructors
+
+### `new WoodcutTreeComponent(props)`
+
+Creates a versioned `WoodcutTree` component.
+
+- `props` [`<ComponentProps & WoodcutTreeComponentProps>`](#types) Configuration of the component to create.
+- Returns: `<WoodcutTreeComponent>`
+
+```ts
+import { WoodcutTreeComponent } from 'att-string-transcoder';
+
+const componentVersion = 3;
+const component = new WoodcutTreeComponent({ version: componentVersion });
+```
+
+---
+
+### `WoodcutTreeComponent.fromBinary(reader, version)`
+
+See [`Component.fromBinary(reader, version)`](./Component.md#componentfrombinaryreader-version)
+
+## Properties
+
+Note that the following properties are sorted in order of appearance when decoding component binary data.
+
+### `hash`
+
+See [`Component.hash`](./Component.md#hash)
+
+---
+
+### `name`
+
+See [`Component.name`](./Component.md#name)
+
+---
+
+### `version`
+
+See [`Component.version`](./Component.md#version)
+
+---
+
+### `presetHash`
+
+- Since: `v3`
+- `<number>`
+
+```ts
+import { WoodcutTreeComponent } from 'att-string-transcoder';
+
+const componentVersion = 3;
+const component = new WoodcutTreeComponent({ version: componentVersion });
+
+const presetHash = component.presetHash;
+// `presetHash` is `0`
+```
+
+---
+
+### `speciesHash`
+
+The hash of the species of the tree prefab this component is attached to.
+
+- Since: `v3`
+- [`<SpeciesHash>`](../src/types/SpeciesHash.ts)
+
+```ts
+import { WoodcutTreeComponent } from 'att-string-transcoder';
+
+const componentVersion = 3;
+const component = new WoodcutTreeComponent({ version: componentVersion });
+
+const speciesHash = component.speciesHash;
+// `speciesHash` is `11232`
+```
+
+## Methods
+
+### `toBinary(version?)`
+
+See [`Component.toBinary(version?)`](./Component.md#tobinaryversion)
+
+---
+
+### `write(writer, version?)`
+
+See [`Component.write(writer, version?)`](./Component.md#writewriter-version)
diff --git a/docs/examples/Alter-a-swords-material.md b/docs/examples/Alter-a-swords-material.md
new file mode 100644
index 0000000..d3334f8
--- /dev/null
+++ b/docs/examples/Alter-a-swords-material.md
@@ -0,0 +1,9 @@
+# Alter a sword's material
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const handle = Prefab.fromSaveString<'Handle_Short'>('...');
+
+handle.getChildPrefab('Guard')?.getChildPrefab('Short_Sword_Blade')?.setMaterial('EvinonSteelAlloy').print();
+```
diff --git a/docs/examples/Crafting-a-rainbow-lantern.md b/docs/examples/Crafting-a-rainbow-lantern.md
new file mode 100644
index 0000000..b50e70a
--- /dev/null
+++ b/docs/examples/Crafting-a-rainbow-lantern.md
@@ -0,0 +1,25 @@
+# Crafting a rainbow lantern
+
+```ts
+import { Entity, Prefab } from 'att-string-transcoder';
+
+const rainbowLantern = new Prefab('Lantern');
+
+const blue = new Entity<'Lantern'>('lantern_bar_01_28734').setMaterial('Mythril');
+const grey = new Entity<'Lantern'>('lantern_bar_02_28742').setMaterial('Iron');
+const purple = new Entity<'Lantern'>('lantern_bar_03_28770').setMaterial('EvinonSteelAlloy');
+const red = new Entity<'Lantern'>('lantern_bar_04_28766').setMaterial('RedIronAlloy');
+const orange = new Entity<'Lantern'>('lantern_bar_05_28738').setMaterial('Copper');
+const yellow = new Entity<'Lantern'>('lantern_bar_06_28778').setMaterial('Gold');
+const green = new Entity<'Lantern'>('lantern_bar_07_28750').setMaterial('OrchiAlloy');
+
+rainbowLantern
+  .addEntity(blue)
+  .addEntity(grey)
+  .addEntity(purple)
+  .addEntity(red)
+  .addEntity(orange)
+  .addEntity(yellow)
+  .addEntity(green)
+  .print();
+```
diff --git a/docs/examples/Flask-of-infinite-teleportation.md b/docs/examples/Flask-of-infinite-teleportation.md
new file mode 100644
index 0000000..869469d
--- /dev/null
+++ b/docs/examples/Flask-of-infinite-teleportation.md
@@ -0,0 +1,9 @@
+# Flask of infinite teleportation
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const flask = new Prefab('Potion_Medium');
+
+flask.setServings(999).print();
+```
diff --git a/docs/examples/Integrate-with-a-bot.md b/docs/examples/Integrate-with-a-bot.md
new file mode 100644
index 0000000..39ae9c6
--- /dev/null
+++ b/docs/examples/Integrate-with-a-bot.md
@@ -0,0 +1,17 @@
+# Integrate with a bot
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+// ...
+
+const commandResult = await botClient.send('...');
+const saveString = commandResult.data.ResultString;
+
+const prefab = Prefab.fromSaveString(saveString);
+prefab.setOnFire();
+
+const newSaveString = prefab.toSaveString();
+
+await botClient.send(`spawn string-raw ${newSaveString}`);
+```
diff --git a/docs/examples/Launch-a-wyrm-spit.md b/docs/examples/Launch-a-wyrm-spit.md
new file mode 100644
index 0000000..d67bc0b
--- /dev/null
+++ b/docs/examples/Launch-a-wyrm-spit.md
@@ -0,0 +1,12 @@
+# Launch a wym spit
+
+```ts
+import { Prefab } from 'att-string-transcoder';
+
+const spit = new Prefab('Wyrm_Spit');
+
+spit.setPosition(playerRightHandPosition);
+spit.setRotation(playerRightHandUpInverted);
+spit.setVelocity(playerRightHandUpInvertedMultiplied);
+spit.print();
+```
diff --git a/docs/isATTPrefabHash.md b/docs/isATTPrefabHash.md
new file mode 100644
index 0000000..962ec8e
--- /dev/null
+++ b/docs/isATTPrefabHash.md
@@ -0,0 +1,22 @@
+# Function: `isATTPrefabHash`
+
+Asserts if a `<number>` is an [`<ATTPrefabHash>`](./ATTPrefabHash.md).
+
+## Signatures
+
+### `isATTPrefabHash(hash)`
+
+- `hash` `<number>` The hash of the prefab.
+- Returns: `<boolean>`
+
+```ts
+import { isATTPrefabHash } from 'att-string-transcoder';
+
+let prefabHash: number;
+prefabHash = 23182;
+// `prefabHash` is of type `number`.
+
+if (isATTPrefabHash(prefabHash)) {
+  // `prefabHash` is of type `ATTPrefabHash`.
+}
+```
diff --git a/docs/isATTPrefabName.md b/docs/isATTPrefabName.md
new file mode 100644
index 0000000..29c92f9
--- /dev/null
+++ b/docs/isATTPrefabName.md
@@ -0,0 +1,22 @@
+# Function: `isATTPrefabName`
+
+Asserts if a `<string>` is an [`<ATTPrefabName>`](./ATTPrefabName.md).
+
+## Signatures
+
+### `isATTPrefabName(name)`
+
+- `name` `<string>` The name of the prefab.
+- Returns: `<boolean>`
+
+```ts
+import { isATTPrefabName } from 'att-string-transcoder';
+
+let prefabName: string;
+prefabName = 'Anvil';
+// `prefabName` is of type `string`.
+
+if (isATTPrefabName(prefabName)) {
+  // `prefabName` is of type `ATTPrefabName`.
+}
+```
diff --git a/docs/isSavableComponent.md b/docs/isSavableComponent.md
new file mode 100644
index 0000000..af7e4ea
--- /dev/null
+++ b/docs/isSavableComponent.md
@@ -0,0 +1,33 @@
+# Function: `isSavablecomponent`
+
+Returns whether or not the given component name belongs to a component that is normally savable on the given prefab hash or name.
+
+## Signatures
+
+### `isSavablecomponent(componentName, prefabHash)`
+
+- `componentName` [`<keyof SupportedPrefabComponents>`](../src/types/SupportedPrefabComponents.ts) The name of the component.
+- `prefabHash` [`<ATTPrefabHash>`](./ATTPrefabHash.md) The hash of the parent prefab.
+- Returns: `<boolean>`
+
+```ts
+import { isSavableComponent } from 'att-string-transcoder';
+
+if (isSavableComponent('NetworkRigidbody', 42230)) {
+  // `Handle_Short` can save `NetworkRigidbody` component data.
+}
+```
+
+### `isSavablecomponent(componentName, prefabName)`
+
+- `componentName` [`<keyof SupportedPrefabComponents>`](../src/types/SupportedPrefabComponents.ts) The name of the component.
+- `prefabName` [`<ATTPrefabName>`](./ATTPrefabName.md) The name of the parent prefab.
+- Returns: `<boolean>`
+
+```ts
+import { isSavablecomponent } from 'att-string-transcoder';
+
+if (isSavableComponent('NetworkRigidbody', 'Handle_Short')) {
+  // `Handle_Short` can save `NetworkRigidbody` component data.
+}
+```
diff --git a/docs/isUnknownComponent.md b/docs/isUnknownComponent.md
new file mode 100644
index 0000000..59cc8bc
--- /dev/null
+++ b/docs/isUnknownComponent.md
@@ -0,0 +1,18 @@
+# Function: `isUnknownComponent`
+
+Asserts if a `component` is an [`UnsupportedComponent`](./UnsupportedComponent.md).
+
+## Signatures
+
+### `isUnknownComponent(component)`
+
+- `component` [`Component`](./Component.md)
+- Returns: `<boolean>`
+
+```ts
+import { isUnknownComponent } from 'att-string-transcoder';
+
+if (isUnknownComponent(component)) {
+  // `component` is of type `UnsupportedComponent`.
+}
+```
diff --git a/docs/readChildren.md b/docs/readChildren.md
new file mode 100644
index 0000000..1ad7d8c
--- /dev/null
+++ b/docs/readChildren.md
@@ -0,0 +1,26 @@
+# Function: `readChildren`
+
+Reads all child prefabs from the given `BinaryReader` and returns an array of `PrefabChild`.
+
+## Signatures
+
+### `readChildren(reader, componentVersions?)`
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` containing the child prefab binary data.
+- `componentVersions` (optional, default latest) `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: [`<Array<PrefabChild>>`](../src/types/PrefabChild.ts)
+
+```ts
+import { BinaryReader, readChildren } from 'att-string-transcoder';
+
+const reader = new BinaryReader('...');
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+const children = readChildren(reader, componentVersions);
+```
diff --git a/docs/readComponent.md b/docs/readComponent.md
new file mode 100644
index 0000000..e29831e
--- /dev/null
+++ b/docs/readComponent.md
@@ -0,0 +1,24 @@
+# Function: `readComponent`
+
+Reads next component from the given `BinaryReader` and returns a `Component` instance.
+
+## Signatures
+
+### `readComponent(reader, hash, name, version)`
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` containing the component binary data.
+- `hash` `<number>` The hash of the component.
+- `name` `<string>` The name of the component.
+- `version` `<number>` The version of the component.
+- Returns: [`<Component>`](./Component.md)
+
+```ts
+import { BinaryReader, readComponent } from 'att-string-transcoder';
+
+const reader = new BinaryReader('...');
+const hash = 2290978823;
+const name = 'NetworkRigidbody';
+const version = 1;
+
+const component = readComponent(reader, hash, name, version);
+```
diff --git a/docs/readComponents.md b/docs/readComponents.md
new file mode 100644
index 0000000..11b643a
--- /dev/null
+++ b/docs/readComponents.md
@@ -0,0 +1,26 @@
+# Function: `readComponents`
+
+Reads all components from the given `BinaryReader` and returns a `PrefabComponents` object.
+
+## Signatures
+
+### `readComponents(reader, versions?)`
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` containing the components binary data.
+- `versions` (optional, default latest) `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: [`<PrefabComponents>`](../src/types/PrefabComponents.ts)
+
+```ts
+import { BinaryReader, readComponents } from 'att-string-transcoder';
+
+const reader = new BinaryReader('...');
+
+const versions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+const component = readComponents(reader, versions);
+```
diff --git a/docs/readEntities.md b/docs/readEntities.md
new file mode 100644
index 0000000..fd6d1fb
--- /dev/null
+++ b/docs/readEntities.md
@@ -0,0 +1,28 @@
+# Function: `readEntities`
+
+Reads all entities from the given `BinaryReader` and returns a `PrefabEntities` object.
+
+## Signatures
+
+### `readEntities(reader, prefabName, componentVersions?)`
+
+- `reader` [`BinaryReader`](./BinaryReader.md) The `BinaryReader` containing the entities binary data.
+- `prefabName` [`ATTPrefabName`](./ATTPrefabName.md) The name of the parent prefab.
+- `componentVersions` (optional, default latest) `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: [`<PrefabEntities>`](../src/types/PrefabEntities.ts)
+
+```ts
+import { BinaryReader, readEntities, type ATTPrefabName } from 'att-string-transcoder';
+
+const reader = new BinaryReader('...');
+const prefabName = 'Handle_Short' as ATTPrefabName;
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+const component = readEntities(reader, prefabName, componentVersions);
+```
diff --git a/docs/writeChildren.md b/docs/writeChildren.md
new file mode 100644
index 0000000..b7605c4
--- /dev/null
+++ b/docs/writeChildren.md
@@ -0,0 +1,34 @@
+# Function: `writeChildren`
+
+Writes given child prefabs to the given `BinaryWriter`.
+
+## Signatures
+
+### `writeChildren(writer, children, componentVersions)`
+
+- `writer` [`BinaryWriter`](./BinaryWriter.md) The `BinaryWriter` to store the binary data into.
+- `children` [`<Array<PrefabChild>>`](../src/types/PrefabChild.ts) The child prefabs to store.
+- `componentVersions` `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter, writeChildren } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+const children = [
+  {
+    parentHash: 0,
+    prefab: new Prefab('Guard')
+  }
+];
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+writeChildren(writer, children, componentVersions);
+```
diff --git a/docs/writeComponents.md b/docs/writeComponents.md
new file mode 100644
index 0000000..f856f09
--- /dev/null
+++ b/docs/writeComponents.md
@@ -0,0 +1,32 @@
+# Function: `writeComponents`
+
+Writes given components to the given `BinaryWriter`.
+
+## Signatures
+
+### `writeComponents(writer, components, versions)`
+
+- `writer` [`BinaryWriter`](./BinaryWriter.md) The `BinaryWriter` to store the binary data into.
+- `components` [`<PrefabComponents>`](../src/types/PrefabComponents.ts) The components to store.
+- `versions` `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter, NetworkRigidbodyComponent, writeComponents } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+const components = {
+  NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+  Unknown: []
+};
+
+const versions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+writeComponents(writer, components, versions);
+```
diff --git a/docs/writeEntities.md b/docs/writeEntities.md
new file mode 100644
index 0000000..7c52e6a
--- /dev/null
+++ b/docs/writeEntities.md
@@ -0,0 +1,31 @@
+# Function: `writeEntities`
+
+Writes given entities to the given `BinaryWriter`.
+
+## Signatures
+
+### `writeEntities(writer, entities, componentVersions)`
+
+- `writer` [`BinaryWriter`](./BinaryWriter.md) The `BinaryWriter` to store the binary data into.
+- `entities` [`<PrefabEntities>`](../src/types/PrefabEntities.ts) The entities to store.
+- `componentVersions` `<Map<number, number>>` A map of component versions to ensure are encoded in the binary data.
+- Returns: `<void>`
+
+```ts
+import { BinaryWriter, Entity, writeEntities } from 'att-string-transcoder';
+
+const writer = new BinaryWriter();
+
+const entities = {
+  Fire_30100: new Entity<'Torch'>('Fire_30100')
+};
+
+const componentVersions = new Map<number, number>([
+  [ComponentHash.NetworkRigidbody, 1],
+  [ComponentHash.PhysicalMaterialPart, 1],
+  [ComponentHash.Pickup, 2]
+  // etc...
+]);
+
+writeEntities(writer, entities, componentVersions);
+```
diff --git a/package.json b/package.json
index 25b2171..e1e86ba 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,7 @@
 {
   "name": "att-string-transcoder",
-  "version": "1.0.1",
-  "description": "Trancode integer strings for A Township Tale.",
-  "main": "build/index.js",
-  "scripts": {
-    "prepare": "npm run build",
-    "prebuild": "rimraf build/",
-    "build": "tsc",
-    "compile": "tsc --noEmit",
-    "pretest": "npm run build",
-    "test": "jest"
-  },
+  "version": "3.1.2",
+  "description": "Trancode save strings for A Township Tale.",
   "author": "Marc Dingena",
   "repository": {
     "type": "git",
@@ -27,29 +18,60 @@
     "transcoder"
   ],
   "license": "MIT",
+  "scripts": {
+    "prepare": "run-s prepare:*",
+    "prepare:husky": "husky install",
+    "prepare:build": "npm run build",
+    "lint": "eslint --fix \"src/**/*.{ts,js}\"",
+    "format": "prettier --write \"+(*.md|src/**/*.{js,ts,json,md})\"",
+    "compile": "tsc --noEmit",
+    "parse": "npm run parse --prefix scripts",
+    "prebuild": "rimraf dist/",
+    "build": "run-p build:*",
+    "build:cjs": "tsc -p tsconfig-cjs.json",
+    "build:esm": "tsc -p tsconfig-esm.json",
+    "postbuild:cjs": "node --loader ts-node/esm ./scripts/postbuild-cjs.ts",
+    "test": "vitest run"
+  },
+  "engines": {
+    "node": ">=20.4.0"
+  },
+  "type": "module",
+  "exports": {
+    ".": {
+      "import": "./dist/esm/index.js",
+      "require": "./dist/cjs/index.js",
+      "default": "./dist/esm/index.js",
+      "types": "./dist/types/index.d.ts"
+    }
+  },
+  "module": "./dist/esm/index.js",
+  "main": "./dist/cjs/index.js",
+  "types": "./dist/types/index.d.ts",
+  "files": [
+    "dist/"
+  ],
   "dependencies": {
     "bitwise": "^2.1.0",
     "ieee754": "^1.2.1"
   },
   "devDependencies": {
-    "@types/jest": "^26.0.24",
-    "husky": "^6.0.0",
-    "jest": "^27.0.6",
-    "lint-staged": "^11.0.0",
-    "prettier": "^2.3.0",
-    "rimraf": "^3.0.2",
-    "ts-jest": "^27.0.4",
-    "typescript": "^4.2.4"
-  },
-  "husky": {
-    "hooks": {
-      "pre-commit": [
-        "lint-staged",
-        "npm run test"
-      ]
-    }
-  },
-  "lint-staged": {
-    "**/*.{js,ts,jsx,tsx,json,css,html}": "prettier --write"
+    "@types/jest": "^29.5.3",
+    "@types/node": "^20.4.2",
+    "@typescript-eslint/eslint-plugin": "^6.1.0",
+    "@typescript-eslint/parser": "^6.1.0",
+    "@vitest/coverage-v8": "^0.33.0",
+    "eslint": "^8.19.0",
+    "eslint-config-prettier": "^8.5.0",
+    "eslint-import-resolver-typescript": "^3.3.0",
+    "eslint-plugin-import": "^2.26.0",
+    "husky": "^8.0.1",
+    "lint-staged": "^13.0.3",
+    "npm-run-all": "^4.1.5",
+    "prettier": "^3.0.0",
+    "rimraf": "^5.0.0",
+    "ts-node": "^10.9.1",
+    "typescript": "^5.4.5",
+    "vitest": "^0.33.0"
   }
 }
diff --git a/scripts/package.json b/scripts/package.json
new file mode 100644
index 0000000..5ddbace
--- /dev/null
+++ b/scripts/package.json
@@ -0,0 +1,6 @@
+{
+  "type": "module",
+  "scripts": {
+    "parse": "node --loader ts-node/esm ./parseSpawnInfodump.ts"
+  }
+}
diff --git a/scripts/parseSpawnInfodump.ts b/scripts/parseSpawnInfodump.ts
new file mode 100644
index 0000000..c03ffee
--- /dev/null
+++ b/scripts/parseSpawnInfodump.ts
@@ -0,0 +1,115 @@
+import fs from 'fs';
+
+import { ATTPrefabs } from '../src/types/ATTPrefabs.js';
+
+import dumpedPrefabs from './spawnInfodump.json' assert { type: 'json' };
+
+type Savable = {
+  hash: number;
+  name: string;
+};
+
+type Embed = {
+  hash: number;
+  name: string;
+  savables: Savable[];
+};
+
+type Prefab = {
+  hash: number;
+  name: string;
+  embedded: Embed[];
+};
+
+function snakeCase(name: string) {
+  return name.replace(/[\s]/g, '_');
+}
+
+function alphabetically(a: [string, unknown], b: [string, unknown]) {
+  return a[0] < b[0] ? -1 : 1;
+}
+
+function parseSavables(savables: Savable[]) {
+  return Object.fromEntries(
+    Object.entries<Savable>(
+      savables.reduce(
+        (savables, savable) => ({
+          ...savables,
+          [snakeCase(savable.name)]: {
+            hash: savable.hash,
+            name: snakeCase(savable.name)
+          }
+        }),
+        {}
+      )
+    ).sort(alphabetically)
+  );
+}
+
+function parseEmbeds(embeds: Embed[]) {
+  return Object.fromEntries(
+    Object.entries<Embed>(
+      embeds.reduce(
+        (entities, entity) => ({
+          ...entities,
+          [`${snakeCase(entity.name)}_${entity.hash}`]: {
+            hash: entity.hash,
+            name: snakeCase(entity.name),
+            savables: parseSavables(entity.savables)
+          }
+        }),
+        {}
+      )
+    ).sort(alphabetically)
+  );
+}
+
+function parsePrefabs(dumpedPrefabs: Prefab[]) {
+  return Object.fromEntries(
+    Object.entries<Prefab>(
+      dumpedPrefabs.reduce(
+        (prefabs, prefab) => ({
+          ...prefabs,
+          [snakeCase(prefab.name)]: {
+            hash: prefab.hash,
+            name: snakeCase(prefab.name),
+            embedded: parseEmbeds(prefab.embedded)
+          }
+        }),
+        {}
+      )
+    ).sort(alphabetically)
+  );
+}
+
+const parsedPrefabs = parsePrefabs(dumpedPrefabs);
+
+const parsedPrefabKeys = Object.keys(parsedPrefabs);
+
+const missingPrefabs = Object.entries(ATTPrefabs).reduce(
+  (missing, [key, prefab]) => (parsedPrefabKeys.includes(key) ? missing : { ...missing, [key]: prefab }),
+  {}
+);
+
+const totalPrefabs = Object.fromEntries(
+  Object.entries({
+    ...missingPrefabs,
+    ...parsedPrefabs
+  }).sort(alphabetically)
+);
+
+const date = new Date();
+const since = `${date.getFullYear()}-${date.getMonth().toString().padStart(2, '0')}-${date
+  .getDate()
+  .toString()
+  .padStart(2, '0')}`;
+
+fs.writeFileSync(
+  '../src/types/ATTPrefabs.ts',
+  `/**
+ * Parsed spawn infodump.
+ * @since ${since}
+ * @version 3.0.0
+ */
+export const ATTPrefabs = ${JSON.stringify(totalPrefabs, null, 2).replace(/"/g, "'")} as const;\n`
+);
diff --git a/scripts/postbuild-cjs.ts b/scripts/postbuild-cjs.ts
new file mode 100644
index 0000000..0db648a
--- /dev/null
+++ b/scripts/postbuild-cjs.ts
@@ -0,0 +1,5 @@
+import fs from 'fs';
+
+const packageJson = JSON.stringify({ 'type': 'commonjs' }, null, 2);
+
+fs.writeFileSync('./dist/cjs/package.json', `${packageJson}\n`);
diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json
new file mode 100644
index 0000000..8d72cc4
--- /dev/null
+++ b/scripts/tsconfig.json
@@ -0,0 +1,18 @@
+{
+  "compilerOptions": {
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",
+    "declaration": true,
+    "declarationMap": false,
+    "sourceMap": false,
+    "outDir": "./build",
+    "skipLibCheck": true,
+    "strict": true,
+    "lib": ["es2017"],
+    "target": "es6",
+    "resolveJsonModule": true
+  },
+  "include": ["./**/*"]
+}
diff --git a/src/BinaryData.test.ts b/src/BinaryData.test.ts
new file mode 100644
index 0000000..a8b1c7f
--- /dev/null
+++ b/src/BinaryData.test.ts
@@ -0,0 +1,416 @@
+import type { BinaryString } from './types/BinaryString.js';
+
+import { BinaryData, type BinaryDataOptions, type UnpackFloatOptions } from './BinaryData.js';
+
+const BUFFER_OFFSET = 0;
+const BYTE_LENGTH = 4;
+const IS_LITTLE_ENDIAN = true;
+const MANTISSA_LENGTH = 23;
+const SIGNED_INTEGER_OFFSET = 2147483648;
+
+describe('new BinaryData()', () => {
+  describe('when given non-binary data', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('topkek');
+      const expectedError = new Error('Binary data string contains invalid characters. Only "0" and "1" are allowed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('BinaryData.fromBoolean()', () => {
+  it('creates a BinaryData instance from a boolean', () => {
+    const expectedBoolean = true;
+    const expectedBinary = '1' as BinaryString; // => expectedBoolean as a binary boolean
+    const data = BinaryData.fromBoolean(expectedBoolean);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toBoolean()).toStrictEqual(expectedBoolean);
+  });
+});
+
+describe('BinaryData.fromFloat()', () => {
+  it('creates a BinaryData instance from a floating point number', () => {
+    const expectedNumber = 1337.42069;
+    const expectedBinary = '01000100101001110010110101110110' as BinaryString; // => expectedNumber as a binary floating point number
+    const data = BinaryData.fromFloat(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toFloat()).toBeCloseTo(expectedNumber, 4);
+  });
+});
+
+describe('BinaryData.fromNumber()', () => {
+  it('creates a BinaryData instance from a number', () => {
+    const expectedNumber = 1337;
+    const expectedBinary = '10100111001' as BinaryString; // => expectedNumber as a binary number
+    const data = BinaryData.fromNumber(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toNumber()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.fromSignedInteger()', () => {
+  it('creates a BinaryData instance from a positive signed integer', () => {
+    const expectedNumber = 133742069;
+    const expectedBinary = '10000111111110001011110111110101' as BinaryString; // => expectedNumber as a binary signed integer
+    const data = BinaryData.fromSignedInteger(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+  });
+
+  it('creates a BinaryData instance from a negative signed integer', () => {
+    const expectedNumber = -694201337;
+    const expectedBinary = '01010110100111110101010000000111' as BinaryString; // => expectedNumber as a binary signed integer
+    const data = BinaryData.fromSignedInteger(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+  });
+
+  describe('when an options argument is passed', () => {
+    const options: BinaryDataOptions = {};
+
+    beforeEach(() => {
+      options.signedIntegerOffset = SIGNED_INTEGER_OFFSET;
+    });
+
+    it('creates a BinaryData instance from a positive signed integer', () => {
+      const expectedNumber = 133742069;
+      const expectedBinary = '10000111111110001011110111110101' as BinaryString; // => expectedNumber as a binary signed integer
+      const data = BinaryData.fromSignedInteger(expectedNumber, options);
+
+      expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+      expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+    });
+
+    it('creates a BinaryData instance from a negative signed integer', () => {
+      const expectedNumber = -694201337;
+      const expectedBinary = '01010110100111110101010000000111' as BinaryString; // => expectedNumber as a binary signed integer
+      const data = BinaryData.fromSignedInteger(expectedNumber, options);
+
+      expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+      expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+    });
+  });
+});
+
+describe('BinaryData.fromUnsignedInteger()', () => {
+  it('creates a BinaryData instance from an unsigned integer', () => {
+    const expectedNumber = 133742069;
+    const expectedBinary = '00000111111110001011110111110101' as BinaryString; // => expectedNumber as a binary unsigned integer
+    const data = BinaryData.fromUnsignedInteger(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toUnsignedInteger()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.fromUnsignedIntegerArray()', () => {
+  it('creates a BinaryData instance from an array of unsigned integers', () => {
+    const expectedNumbers = [1337, 420, 69];
+    const expectedBinary =
+      '000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101' as BinaryString; // => expectedNumbers as binary data
+    const data = BinaryData.fromUnsignedIntegerArray(expectedNumbers);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toUnsignedIntegerArray()).toStrictEqual<number[]>(expectedNumbers);
+  });
+});
+
+describe('BinaryData.fromUnsignedLong()', () => {
+  it('creates a BinaryData instance from an unsigned long integer', () => {
+    const expectedNumber = 133742069;
+    const expectedBinary = '0000011111111000101111011111010100000000000000000000000000000000' as BinaryString; // => expectedNumber as a binary unsigned long integer
+    const data = BinaryData.fromUnsignedLong(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toUnsignedLong()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.fromUnsignedShort()', () => {
+  it('creates a BinaryData instance from an unsigned short integer', () => {
+    const expectedNumber = 1337;
+    const expectedBinary = '0000010100111001' as BinaryString; // => expectedNumber as a binary unsigned short integer
+    const data = BinaryData.fromUnsignedShort(expectedNumber);
+
+    expect(data.toBinaryString()).toStrictEqual<BinaryString>(expectedBinary);
+    expect(data.toUnsignedShort()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.isBinaryString()', () => {
+  it('asserts that a string with valid binary is a BinaryString', () => {
+    const data = '01110110100110101';
+    const result = BinaryData.isBinaryString(data);
+
+    expect(result).toBe(true);
+    expect(data).toStrictEqual<BinaryString>('01110110100110101' as BinaryString);
+  });
+
+  it('asserts that a string with invalid binary is not a BinaryString', () => {
+    const data = '011abc10110100110101';
+    const result = BinaryData.isBinaryString(data);
+
+    expect(result).toBe(false);
+    expect(data).toStrictEqual<string>('011abc10110100110101');
+  });
+});
+
+describe('BinaryData.isSaveString()', () => {
+  it('asserts that a string with valid binary is a SaveString', () => {
+    const data = '1111,2222,3333,|4,5555,1,6666,2,7777,3,8888,4,';
+    const result = BinaryData.isSaveString(data);
+
+    expect(result).toBe(true);
+    expect(data).toStrictEqual<BinaryString>('1111,2222,3333,|4,5555,1,6666,2,7777,3,8888,4,' as BinaryString);
+  });
+
+  it('asserts that a string with invalid binary is not a SaveString', () => {
+    const data = '1111,2222,3333,|4,5555,1,6666,2,7777,3,8888,4'; // missing trailing comma
+    const result = BinaryData.isBinaryString(data);
+
+    expect(result).toBe(false);
+    expect(data).toStrictEqual<string>('1111,2222,3333,|4,5555,1,6666,2,7777,3,8888,4');
+  });
+});
+
+describe('BinaryData.packFloat()', () => {
+  it('converts a JavaScript number into an IEEE754 integer', () => {
+    const packedFloat = BinaryData.packFloat(1337.42069);
+
+    expect(packedFloat).toEqual(1151806838);
+  });
+});
+
+describe('BinaryData.toBinaryString()', () => {
+  it('expresses binary verbatim', () => {
+    const binary = '11110111001100010000';
+    const data = new BinaryData(binary);
+
+    expect(data.toBinaryString()).toStrictEqual(binary);
+  });
+});
+
+describe('BinaryData.toBoolean()', () => {
+  it('expresses binary as a boolean', () => {
+    const expectedBoolean = true;
+    const binary = '1'; // => expectedBoolean as a binary boolean
+    const data = new BinaryData(binary);
+
+    expect(data.toBoolean()).toStrictEqual(expectedBoolean);
+  });
+
+  describe('when binary data is not exactly one bit', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('01').toBoolean();
+      const expectedError = new Error('Boolean binary string must be 1 bit.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('BinaryData.toChar()', () => {
+  it('expresses binary as a char', () => {
+    const expectedChar = 'A';
+    const binary = '01000001'; // => expectedChar as a binary boolean
+    const data = new BinaryData(binary);
+
+    expect(data.toChar()).toStrictEqual(expectedChar);
+  });
+
+  describe('when binary data is not exactly eight bits', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('01').toChar();
+      const expectedError = new Error('Char binary string must be 8 bits.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('BinaryData.toFloat()', () => {
+  describe('when the binary string is of incorrect length', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('0').toFloat();
+      const expectedError = new Error('Floating point number binary string must be 32 bits.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('expresses binary as a number', () => {
+    const expectedNumber = 1337.42069;
+    const binary = '01000100101001110010110101110110'; // => expectedNumber as a binary number
+    const data = new BinaryData(binary);
+
+    expect(data.toFloat()).toBeCloseTo(expectedNumber, 4);
+  });
+});
+
+describe('BinaryData.toNumber()', () => {
+  it('expresses binary as a number', () => {
+    const expectedNumber = 1337;
+    const binary = '10100111001'; // => expectedNumber as a binary number
+    const data = new BinaryData(binary);
+
+    expect(data.toNumber()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.toSignedInteger()', () => {
+  describe('when the binary string is of incorrect length', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('0').toSignedInteger();
+      const expectedError = new Error('Signed integer binary string must be 32 bits.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('expresses binary as a positive signed integer', () => {
+    const expectedNumber = 133742069;
+    const binary = '10000111111110001011110111110101'; // => expectedNumber as a binary signed integer
+    const data = new BinaryData(binary);
+
+    expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+  });
+
+  it('expresses binary as a negative signed integer', () => {
+    const expectedNumber = -694201337;
+    const binary = '01010110100111110101010000000111'; // => expectedNumber as a binary signed integer
+    const data = new BinaryData(binary);
+
+    expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+  });
+
+  describe('when the constructor options are configured', () => {
+    const options: BinaryDataOptions = {};
+
+    beforeEach(() => {
+      options.signedIntegerOffset = SIGNED_INTEGER_OFFSET;
+    });
+
+    it('expresses binary as a positive signed integer', () => {
+      const expectedNumber = 133742069;
+      const binary = '10000111111110001011110111110101'; // => expectedNumber as a binary signed integer
+      const data = new BinaryData(binary, options);
+
+      expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+    });
+
+    it('expresses binary as a negative signed integer', () => {
+      const expectedNumber = -694201337;
+      const binary = '01010110100111110101010000000111'; // => expectedNumber as a binary signed integer
+      const data = new BinaryData(binary, options);
+
+      expect(data.toSignedInteger()).toStrictEqual<number>(expectedNumber);
+    });
+  });
+});
+
+describe('BinaryData.toUnsignedInteger()', () => {
+  describe('when the binary string is of incorrect length', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('0').toUnsignedInteger();
+      const expectedError = new Error('Unsigned integer binary string must be 32 bits.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('expresses binary as an unsigned integer', () => {
+    const expectedNumber = 133742069;
+    const binary = '00000111111110001011110111110101'; // => expectedNumber as an unsigned integer
+    const data = new BinaryData(binary);
+
+    expect(data.toUnsignedInteger()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.toUnsignedIntegerArray()', () => {
+  describe('when the binary string is of incorrect length', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('0').toUnsignedIntegerArray();
+      const expectedError = new Error('Bit count must be divisible by 32.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('expresses binary as an unsigned integer', () => {
+    const expectedNumbers = [1337, 420, 69];
+    const binary = '000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101'; // => expectedNumbers as binary data
+    const data = new BinaryData(binary);
+
+    expect(data.toUnsignedIntegerArray()).toStrictEqual<number[]>(expectedNumbers);
+  });
+});
+
+describe('BinaryData.toUnsignedLong()', () => {
+  describe('when the binary string is of incorrect length', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('0').toUnsignedLong();
+      const expectedError = new Error('Unsigned long integer binary string must be 64 bits.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('expresses binary as an unsigned long integer', () => {
+    const expectedNumber = 133742069;
+    const binary = '0000011111111000101111011111010100000000000000000000000000000000'; // => expectedNumber as an unsigned long integer
+    const data = new BinaryData(binary);
+
+    expect(data.toUnsignedLong()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.toUnsignedShort()', () => {
+  describe('when the binary string is of incorrect length', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryData('0').toUnsignedShort();
+      const expectedError = new Error('Unsigned short integer binary string must be 16 bits.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('expresses binary as an unsigned short integer', () => {
+    const expectedNumber = 1337;
+    const binary = '0000010100111001'; // => expectedNumber as an unsigned short integer
+    const data = new BinaryData(binary);
+
+    expect(data.toUnsignedShort()).toStrictEqual<number>(expectedNumber);
+  });
+});
+
+describe('BinaryData.unpackFloat()', () => {
+  it('converts an IEEE754 integer into a JavaScript number', () => {
+    const unpackedFloat = BinaryData.unpackFloat(1151806838);
+
+    expect(unpackedFloat).toBeCloseTo(1337.42069, 4);
+  });
+
+  describe('when an options argument is passed', () => {
+    const options: UnpackFloatOptions = {};
+
+    beforeEach(() => {
+      options.bufferOffset = BUFFER_OFFSET;
+      options.byteLength = BYTE_LENGTH;
+      options.isLittleEndian = IS_LITTLE_ENDIAN;
+      options.mantissaLength = MANTISSA_LENGTH;
+    });
+
+    it('converts an IEEE754 integer into a JavaScript number', () => {
+      const unpackedFloat = BinaryData.unpackFloat(1151806838, options);
+
+      expect(unpackedFloat).toBeCloseTo(1337.42069, 4);
+    });
+  });
+});
diff --git a/src/BinaryData.ts b/src/BinaryData.ts
new file mode 100644
index 0000000..5e6be31
--- /dev/null
+++ b/src/BinaryData.ts
@@ -0,0 +1,529 @@
+import type { BinaryString } from './types/BinaryString.js';
+import type { SaveString } from './types/SaveString.js';
+import type { Bit } from 'bitwise/types.js';
+
+import { integer as bitwiseInteger } from 'bitwise';
+import { read as ieee754Read, write as ieee754Write } from 'ieee754';
+
+export type BinaryDataOptions = {
+  signedIntegerOffset?: number;
+};
+
+export type UnpackFloatOptions = {
+  bufferOffset?: number;
+  byteLength?: number;
+  isLittleEndian?: boolean;
+  mantissaLength?: number;
+};
+
+const BUFFER_OFFSET = 0;
+const BYTE_LENGTH = 4;
+const IS_LITTLE_ENDIAN = true;
+const MANTISSA_LENGTH = 23;
+const SIGNED_INTEGER_OFFSET = 2147483648;
+
+/**
+ * Deals with data types as understood by _A Township Tale_ game servers.
+ *
+ * @see [Class: `BinaryData`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BinaryData.md)
+ * @since v3.0.0
+ *
+ * @example
+ * import { BinaryData } from 'att-string-transcoder';
+ *
+ * const data = new BinaryData('11110111001100010000');
+ * // or
+ * const data = BinaryData.fromBoolean(true);
+ * // or
+ * const data = BinaryData.fromChar('x');
+ * // or
+ * const data = BinaryData.fromFloat(0.69);
+ * // or
+ * const data = BinaryData.fromNumber(1337);
+ * // or
+ * const data = BinaryData.fromSignedInteger(-420);
+ * // or
+ * const data = BinaryData.fromUnsignedInteger(69420);
+ * // or
+ * const data = BinaryData.fromUnsignedIntegerArray([69420, 133769]);
+ * // or
+ * const data = BinaryData.fromUnsignedLong(133742069);
+ * // or
+ * const data = BinaryData.fromUnsignedShort(420);
+ */
+export class BinaryData {
+  private readonly binary: BinaryString;
+  private readonly signedIntegerOffset: number;
+
+  /**
+   * Creates a data structure from the given binary `data` and lets you express it as other data
+   * types. You may optionally provide additional options in the second argument.
+   *
+   * @see [Class: `BinaryData`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BinaryData.md)
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('11110111001100010000', {
+   *   signedIntegerOffset: 2147483648
+   * });
+   */
+  constructor(binary: string, options?: BinaryDataOptions) {
+    if (!BinaryData.isBinaryString(binary)) {
+      throw new Error('Binary data string contains invalid characters. Only "0" and "1" are allowed.');
+    }
+
+    this.binary = binary;
+    this.signedIntegerOffset = options?.signedIntegerOffset ?? SIGNED_INTEGER_OFFSET;
+  }
+
+  /**
+   * Creates a BinaryData instance from the given boolean.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromBoolean(true);
+   */
+  static fromBoolean(boolean: boolean, options?: BinaryDataOptions): BinaryData {
+    const data = Number(boolean).toString();
+
+    return new BinaryData(data, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given character.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromChar('x');
+   */
+  static fromChar(char: string, options?: BinaryDataOptions): BinaryData {
+    const charCode = char.charCodeAt(0);
+    const data = BinaryData.fromNumber(charCode).toBinaryString().padStart(8, '0');
+
+    return new BinaryData(data, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given floating point number.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromFloat(0.69);
+   */
+  static fromFloat(float: number, options?: BinaryDataOptions): BinaryData {
+    const packedFloat = BinaryData.packFloat(float);
+
+    return BinaryData.fromUnsignedInteger(packedFloat, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given number.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromNumber(1337);
+   */
+  static fromNumber(number: number, options?: BinaryDataOptions): BinaryData {
+    const data = number.toString(2) as BinaryString;
+
+    return new BinaryData(data, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given signed integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromSignedInteger(-420);
+   */
+  static fromSignedInteger(signedInteger: number, options?: BinaryDataOptions): BinaryData {
+    const isPositive = signedInteger >= 0;
+    const integer = isPositive
+      ? signedInteger
+      : signedInteger + (options?.signedIntegerOffset ?? SIGNED_INTEGER_OFFSET);
+
+    const isPositiveBit = Number(isPositive).toString();
+    const integerBits = BinaryData.fromNumber(integer).toBinaryString().padStart(32, '0');
+
+    const data = `${isPositiveBit}${integerBits.slice(1)}`;
+
+    return new BinaryData(data, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given unsigned integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromUnsignedInteger(69420);
+   */
+  static fromUnsignedInteger(unsignedInteger: number, options?: BinaryDataOptions): BinaryData {
+    const binary = BinaryData.fromNumber(unsignedInteger).toBinaryString().padStart(32, '0');
+
+    return new BinaryData(binary, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given comma-separated array of unsigned integers.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromUnsignedIntegerArray([69420, 133769]);
+   */
+  static fromUnsignedIntegerArray(unsignedIntegerArray: number[], options?: BinaryDataOptions): BinaryData {
+    const binary = unsignedIntegerArray
+      .map(unsignedInteger => BinaryData.fromUnsignedInteger(unsignedInteger, options).toBinaryString())
+      .join('');
+
+    return new BinaryData(binary, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given unsigned long integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromUnsignedLong(133742069);
+   */
+  static fromUnsignedLong(unsignedLong: number, options?: BinaryDataOptions): BinaryData {
+    const binary = BinaryData.fromNumber(unsignedLong).toBinaryString().padStart(64, '0');
+    const reorderedBinary = `${binary.slice(32)}${binary.slice(0, 32)}`;
+
+    return new BinaryData(reorderedBinary, options);
+  }
+
+  /**
+   * Creates a BinaryData instance from the given unsigned short integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = BinaryData.fromUnsignedShort(420);
+   */
+  static fromUnsignedShort(unsignedShort: number, options?: BinaryDataOptions): BinaryData {
+    const binary = BinaryData.fromNumber(unsignedShort).toBinaryString().padStart(16, '0');
+
+    return new BinaryData(binary, options);
+  }
+
+  /**
+   * Confirms whether `data` is a string of binary data, i.e. a string of zeroes and ones.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const maybeBinaryString = '11110111001100010000';
+   * // `maybeBinaryString` is of type `string`
+   *
+   * if (BinaryData.isBinaryString(maybeBinaryString)) {
+   *   // `maybeBinaryString` is of type `BinaryString` inside this closure
+   * }
+   */
+  static isBinaryString(data: string): data is BinaryString {
+    const binaryStringPattern = /^[01]+$/;
+
+    return binaryStringPattern.test(data);
+  }
+
+  /**
+   * Confirms whether `data` is a string of unsigned integers and chunk versioning pairs.
+   *
+   * This is also a type assertion function, so if the passed `string` is asserted as a
+   * `BinaryString`, it will be considered as such after calling this function.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const maybeSaveString = '...';
+   * // `maybeSaveString` is of type `string`
+   *
+   * if (BinaryData.isSaveString(maybeSaveString)) {
+   *   // `maybeSaveString` is of type `SaveString` inside this closure
+   * }
+   */
+  static isSaveString(data: string): data is SaveString {
+    const saveStringPattern = /^[0-9,|]+$/;
+
+    const isValidCharacters = saveStringPattern.test(data);
+    const isValidLastCharacter = data.slice(-1) === ',';
+
+    return isValidCharacters && isValidLastCharacter;
+  }
+
+  /**
+   * Converts a JavaScript floating point number into an IEEE754 integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const packedFloat = BinaryData.packFloat(1337.42069);
+   * // `packedFloat` is `1151806838`
+   */
+  static packFloat(number: number): number {
+    const buffer = Buffer.from(new Uint8Array(4));
+    let bits = 0;
+
+    ieee754Write(buffer, number, 0, true, 23, 4);
+
+    const integer = buffer.readUInt32LE(0);
+
+    for (let i = 0; i < 32; i++) {
+      const bit: Bit = bitwiseInteger.getBit(integer, 31 - i);
+
+      bits = bitwiseInteger.setBit(bits, 31 - i, bit);
+    }
+
+    return bits >>> 0;
+  }
+
+  /**
+   * Returns the binary data as a `BinaryString`.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('1111011100110001000');
+   *
+   * const binary = data.toBinaryString();
+   * // `binary` is `'1111011100110001000'`
+   */
+  toBinaryString(): BinaryString {
+    return this.binary;
+  }
+
+  /**
+   * Returns the boolean represenation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('1');
+   *
+   * const boolean = data.toBoolean();
+   * // `boolean` is `true`
+   */
+  toBoolean(): boolean {
+    if (this.binary.length !== 1) throw new Error('Boolean binary string must be 1 bit.');
+
+    return Boolean(Number(this.binary));
+  }
+
+  /**
+   * Returns the character represenation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('01000001');
+   *
+   * const char = data.toChar();
+   * // `char` is `'A'`
+   */
+  toChar(): string {
+    if (this.binary.length !== 8) throw new Error('Char binary string must be 8 bits.');
+
+    return String.fromCharCode(this.toNumber());
+  }
+
+  /**
+   * Returns the floating point number represenation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('01000100101001110010110101110110');
+   *
+   * const float = data.toFloat();
+   * // `float` is approximately `1337.42069`
+   */
+  toFloat(): number {
+    if (this.binary.length !== 32) throw new Error('Floating point number binary string must be 32 bits.');
+
+    const unsignedInteger = this.toUnsignedInteger();
+
+    return BinaryData.unpackFloat(unsignedInteger);
+  }
+
+  /**
+   * Returns the numeric represenation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('10100111001');
+   *
+   * const number = data.toNumber();
+   * // `number` is `1337`
+   */
+  toNumber(): number {
+    return Number(`0b${this.binary}`);
+  }
+
+  /**
+   * Returns the signed integer representation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('01010110100111110101010000000111');
+   *
+   * const signedInteger = data.toSignedInteger();
+   * // `signedInteger` is `-694201337`
+   */
+  toSignedInteger(): number {
+    if (this.binary.length !== 32) throw new Error('Signed integer binary string must be 32 bits.');
+
+    const isPositive = Boolean(Number(this.binary.slice(0, 1)));
+    const integer = Number(`0b0${this.binary.slice(1)}`);
+
+    return isPositive ? integer : integer - this.signedIntegerOffset;
+  }
+
+  /**
+   * Returns the unsigned integer representation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('00000111111110001011110111110101');
+   *
+   * const unsignedInteger = data.toUnsignedInteger();
+   * // `unsignedInteger` is `133742069`
+   */
+  toUnsignedInteger(): number {
+    if (this.binary.length !== 32) throw new Error('Unsigned integer binary string must be 32 bits.');
+
+    return this.toNumber();
+  }
+
+  /**
+   * Returns the binary data as a comma-separated array of unsigned integers.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101');
+   *
+   * const unsignedIntegers = data.toUnsignedIntegerArray();
+   * // `unsignedIntegers` is `[1337, 420, 69]`
+   */
+  toUnsignedIntegerArray(): number[] {
+    if (this.binary.length % 32 !== 0) throw Error('Bit count must be divisible by 32.');
+
+    const chunks = this.binary.match(/.{32}/g) as RegExpMatchArray;
+
+    return chunks.map(bits => new BinaryData(bits).toUnsignedInteger());
+  }
+
+  /**
+   * Returns the unsigned long integer representation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('0000011111111000101111011111010100000000000000000000000000000000');
+   *
+   * const unsignedLongInteger = data.toUnsignedLong();
+   * // `unsignedLongInteger` is `133742069`
+   */
+  toUnsignedLong(): number {
+    if (this.binary.length !== 64) throw new Error('Unsigned long integer binary string must be 64 bits.');
+
+    return Number(`0b${this.binary.slice(32)}${this.binary.slice(0, 32)}`);
+  }
+
+  /**
+   * Returns the unsigned short integer representation of the binary data.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const data = new BinaryData('0000010100111001');
+   *
+   * const unsignedShortInteger = data.toUnsignedShort();
+   * // `unsignedShortInteger` is `1337`
+   */
+  toUnsignedShort(): number {
+    if (this.binary.length !== 16) throw new Error('Unsigned short integer binary string must be 16 bits.');
+
+    return this.toNumber();
+  }
+
+  /**
+   * Converts an IEEE754 integer into a JavaScript floating point number.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryData } from 'att-string-transcoder';
+   *
+   * const unpackedFloat = BinaryData.unpackFloat(1151806838);
+   * // `unpackedFloat` is approximately `1337.42069`
+   */
+  static unpackFloat(unsignedInteger: number, options?: UnpackFloatOptions): number {
+    const bufferOffset = options?.bufferOffset ?? BUFFER_OFFSET;
+    const byteLength = options?.byteLength ?? BYTE_LENGTH;
+    const isLittleEndian = options?.isLittleEndian ?? IS_LITTLE_ENDIAN;
+    const mantissaLength = options?.mantissaLength ?? MANTISSA_LENGTH;
+
+    const buffer = Buffer.from(new Uint8Array(4));
+
+    buffer.writeUInt32LE(unsignedInteger);
+
+    return ieee754Read(buffer, bufferOffset, isLittleEndian, mantissaLength, byteLength);
+  }
+}
diff --git a/src/BinaryReader.test.ts b/src/BinaryReader.test.ts
new file mode 100644
index 0000000..a839d3b
--- /dev/null
+++ b/src/BinaryReader.test.ts
@@ -0,0 +1,155 @@
+import type { BinaryString } from './types/BinaryString.js';
+
+import { BinaryReader } from './BinaryReader.js';
+
+describe('new BinaryReader()', () => {
+  describe('when given non-binary data', () => {
+    it('throws an error', () => {
+      const data = 'topkek';
+      const expectedToThrow = () => new BinaryReader(data);
+      const expectedError = new Error('Binary data string contains invalid characters. Only "0" and "1" are allowed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('BinaryReader.readBits()', () => {
+  it('returns the amount of given bits', () => {
+    const data = '0001001101111111' as BinaryString;
+    const reader = new BinaryReader(data);
+    const read = reader.readBits(8);
+
+    expect(read).toStrictEqual('00010011');
+  });
+
+  it('continues to read on subsequent reads', () => {
+    const data = '0001001101111111' as BinaryString;
+    const reader = new BinaryReader(data);
+    const read1 = reader.readBits(8);
+    const read2 = reader.readBits(4);
+    const read3 = reader.readBits(4);
+
+    expect(read1).toStrictEqual('00010011');
+    expect(read2).toStrictEqual('0111');
+    expect(read3).toStrictEqual('1111');
+  });
+
+  describe('when reading more bits than are stored in the binary string data', () => {
+    it('throws an error', () => {
+      const data = '0001001101111111' as BinaryString;
+      const reader = new BinaryReader(data);
+      const expectedToThrow = () => reader.readBits(data.length + 1);
+      const expectedError = new Error(
+        `Cannot read ${data.length + 1} bits from binary at index 0. Binary is only ${data.length} bits.`
+      );
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('BinaryReader.readBoolean()', () => {
+  it('returns a Boolean', () => {
+    const data = '10' as BinaryString;
+    const reader = new BinaryReader(data);
+
+    expect(reader.readBoolean()).toStrictEqual(true);
+    expect(reader.readBoolean()).toStrictEqual(false);
+  });
+});
+
+describe('BinaryReader.readChar()', () => {
+  it('returns a single character string', () => {
+    const data = '01000001011000100110001101000100' as BinaryString; // "AbcD"
+    const reader = new BinaryReader(data);
+
+    expect(reader.readChar()).toStrictEqual('A');
+    expect(reader.readChar()).toStrictEqual('b');
+    expect(reader.readChar()).toStrictEqual('c');
+    expect(reader.readChar()).toStrictEqual('D');
+  });
+});
+
+describe('BinaryReader.readFloat()', () => {
+  it('returns a floating point number', () => {
+    const expectedNumber = 1337.42069;
+    const data = '01000100101001110010110101110110' as BinaryString; // ~1337.42069
+    const reader = new BinaryReader(data);
+
+    expect(reader.readFloat()).toBeCloseTo(expectedNumber, 4);
+  });
+});
+
+describe('BinaryReader.readSignedInteger()', () => {
+  it('returns a signed integer', () => {
+    const expectedNumber = -694201337;
+    const data = '01010110100111110101010000000111' as BinaryString; // -694201337
+    const reader = new BinaryReader(data);
+
+    expect(reader.readSignedInteger()).toStrictEqual(expectedNumber);
+  });
+});
+
+describe('BinaryReader.readString()', () => {
+  it('returns a string', () => {
+    const expectedString = 'Hello, world!';
+    const data =
+      '000000000000110101001000011001010010110001101111011011000110110001110010011011110111011100100000011011000110010000100001' as BinaryString;
+    const reader = new BinaryReader(data);
+
+    expect(reader.readString()).toStrictEqual(expectedString);
+  });
+
+  describe('when the string has length of zero', () => {
+    it('returns an empty string', () => {
+      const expectedString = '';
+      const data = '0000000000000000' as BinaryString; // length bits that are read before interpreting string data
+      const reader = new BinaryReader(data);
+
+      expect(reader.readString()).toStrictEqual(expectedString);
+    });
+  });
+
+  describe('when the binary string data is not aligned', () => {
+    it('aligns the bits and returns a string', () => {
+      const expectedString = 'Hello, world!';
+      const data =
+        '11100000000000011010000001001000011011110110110001101100011001010110111101110111001000000010110000100001011001000110110001110010' as BinaryString;
+      const reader = new BinaryReader(data);
+
+      expect(reader.readBits(3)).toStrictEqual('111');
+      expect(reader.readString()).toStrictEqual(expectedString);
+    });
+  });
+});
+
+describe('BinaryReader.readUnsignedInteger()', () => {
+  it('returns an unsigned integer', () => {
+    const expectedNumber = 133742069;
+    const data = '00000111111110001011110111110101' as BinaryString;
+    const reader = new BinaryReader(data);
+
+    expect(reader.readUnsignedInteger()).toStrictEqual(expectedNumber);
+  });
+});
+
+describe('BinaryReader.readUnsignedLong()', () => {
+  it('returns an unsigned integer', () => {
+    const expectedNumber = 133742069;
+    const data = '0000011111111000101111011111010100000000000000000000000000000000' as BinaryString;
+    const reader = new BinaryReader(data);
+
+    expect(reader.readUnsignedLong()).toStrictEqual(expectedNumber);
+  });
+});
+
+describe('BinaryReader.readUnsignedShort()', () => {
+  it('returns an unsigned integer', () => {
+    const expectedNumber = 1337;
+    const data = '0000010100111001' as BinaryString;
+    const reader = new BinaryReader(data);
+
+    expect(reader.readUnsignedShort()).toStrictEqual(expectedNumber);
+  });
+});
diff --git a/src/BinaryReader.ts b/src/BinaryReader.ts
new file mode 100644
index 0000000..442b903
--- /dev/null
+++ b/src/BinaryReader.ts
@@ -0,0 +1,263 @@
+import type { BinaryString } from './types/BinaryString.js';
+
+import { BinaryData, type BinaryDataOptions } from './BinaryData.js';
+
+/**
+ * Handles the controlled consumption of binary data from ATT save strings.
+ *
+ * @see [Class: `BinaryReader`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BinaryReader.md)
+ * @since v3.0.0
+ *
+ * @example
+ * import { BinaryReader } from 'att-string-transcoder';
+ *
+ * const reader = new BinaryReader('11110111001100010000');
+ *
+ * const firstByte = reader.readBits(8);
+ * // `firstByte` is `'11110111'`
+ */
+export class BinaryReader {
+  private data: BinaryString;
+  private index = { current: 0 };
+  private length: number;
+
+  /**
+   * Creates a reader to extract information from `data` using various read methods.
+   *
+   * @see [Class: `BinaryReader`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BinaryReader.md)
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('11110111001100010000');
+   */
+  constructor(data: string) {
+    if (!BinaryData.isBinaryString(data)) {
+      throw new Error('Binary data string contains invalid characters. Only "0" and "1" are allowed.');
+    }
+
+    this.data = data;
+    this.length = data.length;
+  }
+
+  /**
+   * Reads the next `bitCount` bits from the binary string.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('11110111001100010000');
+   *
+   * const firstByte = reader.readBits(8);
+   * // `firstByte` is `'11110111'`
+   */
+  readBits(bitCount: number): BinaryString {
+    if (this.index.current + bitCount > this.length) {
+      throw Error(
+        `Cannot read ${bitCount} bits from binary at index ${this.index.current}. Binary is only ${this.length} bits.`
+      );
+    }
+
+    return this.data.slice(this.index.current, (this.index.current += bitCount)) as BinaryString;
+  }
+
+  /**
+   * Reads the next bit from the binary string and returns `true` for `"1"` and `false` for `"0"`.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('10');
+   *
+   * const boolean1 = reader.readBoolean();
+   * // `boolean1` is `true`
+   * const boolean2 = reader.readBoolean();
+   * // `boolean2` is `false`
+   */
+  readBoolean(options?: BinaryDataOptions): boolean {
+    const bit = this.readBits(1);
+
+    return new BinaryData(bit, options).toBoolean();
+  }
+
+  /**
+   * Reads the next 8 bits from the binary string and returns the reconstructed string character.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('01000001011000100110001101000100');
+   *
+   * const char1 = reader.readChar();
+   * // `char1` is `'A'`
+   * const char2 = reader.readChar();
+   * // `char2` is `'b'`
+   * const char3 = reader.readChar();
+   * // `char3` is `'c'`
+   * const char4 = reader.readChar();
+   * // `char4` is `'D'`
+   */
+  readChar(options?: BinaryDataOptions): string {
+    const bits = this.readBits(8);
+
+    return new BinaryData(bits, options).toChar();
+  }
+
+  /**
+   * Reads the next 32 bits from the binary string and returns the reconstructed floating point number.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('01000100101001110010110101110110');
+   *
+   * const float = reader.readFloat();
+   * // `float` is approximately `1337.42069`
+   */
+  readFloat(options?: BinaryDataOptions): number {
+    const bits = this.readBits(32);
+
+    return new BinaryData(bits, options).toFloat();
+  }
+
+  /**
+   * Reads the next 32 bits from the binary string and returns the reconstructed signed integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('01010110100111110101010000000111');
+   *
+   * const signedInteger = reader.readSignedInteger();
+   * // `signedInteger` is `-694201337`
+   */
+  readSignedInteger(options?: BinaryDataOptions): number {
+    const bits = this.readBits(32);
+
+    return new BinaryData(bits, options).toSignedInteger();
+  }
+
+  /**
+   * Reads the next 16 bits from the binary string, then reads the number of bits as instructed and
+   * returns the reconstructed string text.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('000000000000110101001000011001010010110001101111011011000110110001110010011011110111011100100000011011000110010000100001');
+   *
+   * const string = reader.readString();
+   * // `string` is `'Hello, world!'`
+   */
+  readString(): string {
+    const length = this.readUnsignedShort();
+
+    if (length === 0) return '';
+
+    /* Align bits. */
+    const offset = this.index.current % 8 === 0 ? 0 : 8 - (this.index.current % 8);
+
+    if (offset > 0) this.readBits(offset);
+
+    let currentByte = (this.index.current % 32) / 8;
+
+    /* Read garbled text from binary. */
+    let textBuffer = '';
+
+    while (textBuffer.length < length) {
+      textBuffer += this.readChar();
+    }
+
+    /* Untangle garbled text. */
+    let text = '';
+    let bufferIndex = 0;
+
+    while (currentByte < 4 && bufferIndex < length) {
+      text += textBuffer[bufferIndex++];
+      currentByte++;
+    }
+
+    while (bufferIndex + 4 <= length) {
+      const chars = textBuffer.substr(bufferIndex, 4);
+
+      text += chars.split('').reverse().join('');
+      bufferIndex += 4;
+    }
+
+    while (bufferIndex < length) {
+      text += textBuffer[bufferIndex++];
+    }
+
+    return text;
+  }
+
+  /**
+   * Reads the next 32 bits from the binary string and returns the reconstructed unsigned integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('00000111111110001011110111110101');
+   *
+   * const unsignedInteger = reader.readUnsignedInteger();
+   * // `unsignedInteger` is `133742069`
+   */
+  readUnsignedInteger(options?: BinaryDataOptions): number {
+    const bits = this.readBits(32);
+
+    return new BinaryData(bits, options).toUnsignedInteger();
+  }
+
+  /**
+   * Reads the next 64 bits from the binary string and returns the reconstructed unsigned long integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('0000011111111000101111011111010100000000000000000000000000000000');
+   *
+   * const unsignedLongInteger = reader.readUnsignedLong();
+   * // `unsignedLongInteger` is `133742069`
+   */
+  readUnsignedLong(options?: BinaryDataOptions): number {
+    const bits = this.readBits(64);
+
+    return new BinaryData(bits, options).toUnsignedLong();
+  }
+
+  /**
+   * Reads the next 16 bits from the binary string and returns the reconstructed unsigned short integer.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('0000010100111001');
+   *
+   * const unsignedShortInteger = reader.readUnsignedShort();
+   * // `unsignedShortInteger` is `1337`
+   */
+  readUnsignedShort(options?: BinaryDataOptions): number {
+    const bits = this.readBits(16);
+
+    return new BinaryData(bits, options).toUnsignedShort();
+  }
+}
diff --git a/src/BinaryWriter.test.ts b/src/BinaryWriter.test.ts
new file mode 100644
index 0000000..882557b
--- /dev/null
+++ b/src/BinaryWriter.test.ts
@@ -0,0 +1,146 @@
+import { BinaryWriter } from './BinaryWriter.js';
+
+let writer: BinaryWriter;
+
+beforeEach(() => {
+  writer = new BinaryWriter();
+});
+
+describe('BinaryWriter.flush()', () => {
+  it('returns the accumulated data inside BinaryWriter', () => {
+    const flush1 = writer.flush();
+    writer.writeBits('0001');
+    const flush2 = writer.flush();
+    writer.writeBits('01');
+    writer.writeBits('01');
+    const flush3 = writer.flush();
+
+    expect(flush1).toStrictEqual('');
+    expect(flush2).toStrictEqual('0001');
+    expect(flush3).toStrictEqual('0101');
+  });
+});
+
+describe('BinaryWriter.writeBits()', () => {
+  it('stores the bits verbatim as a binary string', () => {
+    const bits = '0001001101111111';
+    const expectedBinary = bits;
+    writer.writeBits(bits);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+
+  describe('when given non-binary data', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new BinaryWriter().writeBits('topkek');
+      const expectedError = new Error('Binary data string contains invalid characters. Only "0" and "1" are allowed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('BinaryWriter.writeBoolean()', () => {
+  it('stores the boolean as a binary string', () => {
+    const boolean = true;
+    const expectedBinary = '1';
+    writer.writeBoolean(boolean);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
+
+describe('BinaryWriter.writeChar()', () => {
+  it('stores the character as a binary string', () => {
+    const char = 'A';
+    const expectedBinary = '01000001';
+    writer.writeChar(char);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
+
+describe('BinaryWriter.writeFloat()', () => {
+  it('stores the floating point number as a binary string', () => {
+    const float = 1337.42069;
+    const expectedBinary = '01000100101001110010110101110110';
+    writer.writeFloat(float);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
+
+describe('BinaryWriter.writeSignedInteger()', () => {
+  it('stores the signed integer as a binary string', () => {
+    const signedInteger = -694201337;
+    const expectedBinary = '01010110100111110101010000000111';
+    writer.writeSignedInteger(signedInteger);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
+
+describe('BinaryWriter.writeString()', () => {
+  it('stores the string as a binary string', () => {
+    const string = 'Hello, world!';
+    const expectedBinary =
+      '000000000000110101001000011001010010110001101111011011000110110001110010011011110111011100100000011011000110010000100001';
+    writer.writeString(string);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+
+  describe('when the string has length of zero', () => {
+    it('stores an empty string', () => {
+      const string = '';
+      const expectedBinary = '0000000000000000';
+      writer.writeString(string);
+
+      expect(writer.flush()).toStrictEqual(expectedBinary);
+    });
+  });
+
+  describe('when the binary string data is not aligned', () => {
+    it('aligns the bits and stores a string', () => {
+      const precedingData = '111';
+      writer.writeBits(precedingData);
+
+      const string = 'Hello, world!';
+      const expectedBinary =
+        '11100000000000011010000001001000011011110110110001101100011001010110111101110111001000000010110000100001011001000110110001110010';
+      writer.writeString(string);
+
+      expect(writer.flush()).toStrictEqual(expectedBinary);
+    });
+  });
+});
+
+describe('BinaryWriter.writeUnsignedInteger()', () => {
+  it('stores the floating point number as a binary string', () => {
+    const unsignedInteger = 133742069;
+    const expectedBinary = '00000111111110001011110111110101';
+    writer.writeUnsignedInteger(unsignedInteger);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
+
+describe('BinaryWriter.writeUnsignedLong()', () => {
+  it('stores the floating point number as a binary string', () => {
+    const unsignedLong = 133742069;
+    const expectedBinary = '0000011111111000101111011111010100000000000000000000000000000000';
+    writer.writeUnsignedLong(unsignedLong);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
+
+describe('BinaryWriter.writeUnsignedShort()', () => {
+  it('stores the floating point number as a binary string', () => {
+    const unsignedShort = 1337;
+    const expectedBinary = '0000010100111001';
+    writer.writeUnsignedShort(unsignedShort);
+
+    expect(writer.flush()).toStrictEqual(expectedBinary);
+  });
+});
diff --git a/src/BinaryWriter.ts b/src/BinaryWriter.ts
new file mode 100644
index 0000000..299ecf5
--- /dev/null
+++ b/src/BinaryWriter.ts
@@ -0,0 +1,247 @@
+import type { BinaryString } from './types/BinaryString.js';
+
+import { BinaryData } from './BinaryData.js';
+
+/**
+ * Handles the controlled storing of binary data for ATT save strings.
+ *
+ * @see [Class: `BinaryWriter`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BinaryWriter.md)
+ * @since v3.0.0
+ *
+ * @example
+ * import { BinaryWriter } from 'att-string-transcoder';
+ *
+ * const writer = new BinaryWriter();
+ *
+ * writer.writeBoolean(true);
+ *
+ * const output = writer.flush();
+ * // `output` is `'1'`
+ */
+export class BinaryWriter {
+  private data: string;
+
+  /**
+   * Creates a writer to store information using various write methods.
+   *
+   * @see [Class: `BinaryWriter`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BinaryWriter.md)
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   */
+  constructor() {
+    this.data = '' as BinaryString;
+  }
+
+  /**
+   * Returns the stored binary string and resets the BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeBoolean(true); // internal memory is `'1'`
+   * writer.writeBoolean(true); // internal memory is `'11'`
+   * writer.writeBoolean(true); // internal memory is `'111'`
+   *
+   * const output = writer.flush(); // internal memory is `''`
+   * // `output` is `'111'`
+   */
+  flush(): BinaryString {
+    const data = this.data;
+    this.data = '';
+
+    return data as BinaryString;
+  }
+
+  /**
+   * Writes raw binary data into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeBits('11110111001100010000');
+   */
+  writeBits(data: string): void {
+    if (!BinaryData.isBinaryString(data)) {
+      throw new Error('Binary data string contains invalid characters. Only "0" and "1" are allowed.');
+    }
+
+    this.data += data;
+  }
+
+  /**
+   * Writes a boolean into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeBoolean(true);
+   */
+  writeBoolean(boolean: boolean): void {
+    this.data += BinaryData.fromBoolean(boolean).toBinaryString();
+  }
+
+  /**
+   * Writes a character into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeChar('x');
+   */
+  writeChar(char: string): void {
+    this.data += BinaryData.fromChar(char).toBinaryString();
+  }
+
+  /**
+   * Writes a floating point number into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeFloat(0.69);
+   */
+  writeFloat(float: number): void {
+    this.data += BinaryData.fromFloat(float).toBinaryString();
+  }
+
+  /**
+   * Writes a signed integer into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeSignedInteger(-420);
+   */
+  writeSignedInteger(signedInteger: number): void {
+    this.data += BinaryData.fromSignedInteger(signedInteger).toBinaryString();
+  }
+
+  /**
+   * Writes a string into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeString('Hello, world!');
+   */
+  writeString(string: string): void {
+    this.writeUnsignedShort(string.length);
+
+    if (string.length === 0) return;
+
+    /* Align bits. */
+    const index = this.data.length;
+    const offset = index % 8 === 0 ? 0 : 8 - (index % 8);
+
+    if (offset > 0) {
+      const alignBits = '0'.repeat(offset);
+
+      this.writeBits(alignBits);
+    }
+
+    let currentByte = (this.data.length % 32) / 8;
+
+    /* Garble text, ATT style. */
+    let textBuffer = '';
+    let bufferIndex = 0;
+
+    while (currentByte++ < 4 && bufferIndex < string.length) {
+      textBuffer += string[bufferIndex++];
+    }
+
+    while (bufferIndex + 4 <= string.length) {
+      const chars = string.substr(bufferIndex, 4);
+
+      textBuffer += chars.split('').reverse().join('');
+      bufferIndex += 4;
+    }
+
+    while (bufferIndex < string.length) {
+      textBuffer += string[bufferIndex++];
+    }
+
+    for (const character of textBuffer) {
+      this.writeChar(character);
+    }
+  }
+
+  /**
+   * Writes an unsigned integer into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeUnsignedInteger(69420);
+   */
+  writeUnsignedInteger(unsignedInteger: number): void {
+    this.data += BinaryData.fromUnsignedInteger(unsignedInteger).toBinaryString();
+  }
+
+  /**
+   * Writes an unsigned long integer into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeUnsignedLong(133742069);
+   */
+  writeUnsignedLong(unsignedLong: number): void {
+    this.data += BinaryData.fromUnsignedLong(unsignedLong).toBinaryString();
+  }
+
+  /**
+   * Writes an unsigned short integer into BinaryWriter's internal memory.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   *
+   * writer.writeUnsignedShort(1337);
+   */
+  writeUnsignedShort(unsignedShort: number): void {
+    this.data += BinaryData.fromUnsignedShort(unsignedShort).toBinaryString();
+  }
+}
diff --git a/src/EmbeddedEntityHash.ts b/src/EmbeddedEntityHash.ts
deleted file mode 100644
index 52589a8..0000000
--- a/src/EmbeddedEntityHash.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export enum EmbeddedEntityHash {
-  Fire = 30100
-}
diff --git a/src/Entity.test.ts b/src/Entity.test.ts
new file mode 100644
index 0000000..a0aad5d
--- /dev/null
+++ b/src/Entity.test.ts
@@ -0,0 +1,477 @@
+import type { BinaryString } from './types/BinaryString.js';
+
+import { BinaryData } from './BinaryData.js';
+import { BinaryReader } from './BinaryReader.js';
+import { BinaryWriter } from './BinaryWriter.js';
+import { Entity } from './Entity.js';
+import { Prefab } from './Prefab.js';
+import { HeatSourceBaseComponent } from './components/HeatSourceBaseComponent.js';
+import { NetworkRigidbodyComponent } from './components/NetworkRigidbodyComponent.js';
+import { PhysicalMaterialPartComponent } from './components/PhysicalMaterialPartComponent.js';
+import { UnsupportedComponent } from './components/UnsupportedComponent.js';
+import { ComponentHash } from './types/ComponentHash.js';
+import { PhysicalMaterialPartHash } from './types/PhysicalMaterialPartHash.js';
+
+describe('new Entity()', () => {
+  describe('when given the required props', () => {
+    it('creates an instance of the Entity class', () => {
+      const prefabName = 'Torch';
+      const entityHash = 30100;
+      const entityName = 'Fire';
+
+      const entity = new Entity<typeof prefabName>(`${entityName}_${entityHash}`);
+
+      expect(entity.hash).toStrictEqual(entityHash);
+      expect(entity.name).toStrictEqual(entityName);
+      expect(entity.isAlive).toStrictEqual(true);
+      expect(entity.components).toStrictEqual({ Unknown: [] });
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('creates an instance of the Entity class', () => {
+      const prefabName = 'Torch';
+      const entityHash = 30100;
+      const entityName = 'Fire';
+      const entityIsAlive = true;
+
+      const entity = new Entity<typeof prefabName>(`${entityName}_${entityHash}`, {
+        hash: entityHash,
+        isAlive: entityIsAlive,
+        components: {
+          HeatSourceBase: new HeatSourceBaseComponent({
+            version: 1,
+            isLit: true,
+            progress: 0.69
+          })
+        }
+      });
+
+      expect(entity.hash).toStrictEqual(entityHash);
+      expect(entity.name).toStrictEqual(entityName);
+      expect(entity.isAlive).toStrictEqual(entityIsAlive);
+      expect(entity.components).toStrictEqual({
+        HeatSourceBase: new HeatSourceBaseComponent({
+          version: 1,
+          isLit: true,
+          progress: 0.69
+        }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an "Unknown" key and no additional hash property', () => {
+    it('throws an error', () => {
+      const expectedToThrow = () => new Entity('Unknown');
+      const expectedError = new Error('You must manually pass an entity hash when instantiating an "Unknown" Entity.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('Entity.addComponent()', () => {
+  let entity: Entity<'Standard_Side_Pouch_Attachment'>;
+
+  beforeEach(() => {
+    entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+  });
+
+  it('adds a component to the entity', () => {
+    const component = new PhysicalMaterialPartComponent({ version: 1, materialHash: 1337 });
+
+    entity.addComponent(component);
+
+    expect(entity.components).toStrictEqual({
+      PhysicalMaterialPart: component,
+      Unknown: []
+    });
+  });
+});
+
+describe('Entity.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+  const prefabName = 'Torch';
+  const entityHash = 30100;
+  const entityName = 'Fire';
+  const prefab = new Prefab(prefabName, {
+    entities: {
+      Fire_30100: new Entity<typeof prefabName>(`${entityName}_${entityHash}`, {
+        hash: entityHash,
+        isAlive: false,
+        components: {
+          HeatSourceBase: new HeatSourceBaseComponent({
+            version: 1,
+            isLit: true,
+            progress: 0.69
+          })
+        }
+      })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // Component hash === termination hash.
+    reader.readUnsignedInteger(); // Entity hash === entityHash.
+    reader.readUnsignedInteger(); // Entity data length.
+
+    fastForwardedReader = reader;
+  });
+
+  describe('when given required EntityFromBinaryProps', () => {
+    it('creates an instance of the Entity class using the given BinaryReader', () => {
+      const props = { key: `${entityName}_${entityHash}`, hash: entityHash };
+      const entity = Entity.fromBinary(fastForwardedReader, props);
+
+      expect(entity).toBeInstanceOf(Entity);
+      expect(entity.hash).toStrictEqual(entityHash);
+      expect(entity.name).toStrictEqual(entityName);
+      expect(entity.isAlive).toStrictEqual(false);
+    });
+  });
+
+  describe('when given additional EntityFromBinaryProps', () => {
+    it('creates an instance of the Entity class using the given BinaryReader', () => {
+      const componentVersions = new Map<number, number>([[4109360768, 1]]);
+      const props = { key: `${entityName}_${entityHash}`, hash: entityHash, componentVersions };
+      const entity = Entity.fromBinary(fastForwardedReader, props);
+
+      expect(entity).toBeInstanceOf(Entity);
+      expect(entity.hash).toStrictEqual(entityHash);
+      expect(entity.name).toStrictEqual(entityName);
+      expect(entity.isAlive).toStrictEqual(false);
+      expect(entity.components).toStrictEqual({
+        HeatSourceBase: new HeatSourceBaseComponent({
+          version: 1,
+          isLit: true,
+          progress: 0.6899999976158142
+        }),
+        Unknown: []
+      });
+    });
+  });
+});
+
+describe('Entity.getMaterial()', () => {
+  describe('when the entity has no PhysicalMaterialPart component', () => {
+    it('returns materialHash of zero', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+      delete entity.components.PhysicalMaterialPart;
+
+      const materialHash = entity.getMaterial();
+
+      expect(materialHash).toStrictEqual(0);
+    });
+  });
+
+  describe('when the prefab has a PhysicalMaterialPart component with materialHash', () => {
+    it('returns the stored isKinematic', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({
+            version: 1,
+            materialHash: PhysicalMaterialPartHash.EvinonSteelAlloy
+          })
+        }
+      });
+
+      const materialHash = entity.getMaterial();
+
+      expect(materialHash).toStrictEqual(31502);
+    });
+  });
+});
+
+describe('Entity.removeAllComponents()', () => {
+  it('removes all components from the entity', () => {
+    const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+      components: {
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+        Unknown: [
+          new UnsupportedComponent({
+            hash: 1337,
+            name: 'Unknown',
+            rawData: '1111011100110001000' as BinaryString,
+            version: 1
+          })
+        ]
+      }
+    });
+
+    entity.removeAllComponents();
+
+    expect(entity.components).toStrictEqual({ Unknown: [] });
+  });
+});
+
+describe('Entity.removeComponent()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 })
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => entity.removeComponent();
+      const expectedError = new Error('You must pass a component hash or name to remove from this entity.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given a valid component hash', () => {
+    it('removes all matching components from the entity', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 })
+        }
+      });
+
+      entity.removeComponent(2290978823);
+
+      expect(entity.components).toStrictEqual({
+        PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given a valid component name', () => {
+    it('removes all matching components from the entity', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 })
+        }
+      });
+
+      entity.removeComponent('NetworkRigidbody');
+
+      expect(entity.components).toStrictEqual({
+        PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an invalid component hash', () => {
+    it('removes zero components from the entity', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 })
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      entity.removeComponent(0);
+
+      expect(entity.components).toStrictEqual({
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an unknown component hash', () => {
+    it('removes all matching components from the entity', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+          // @ts-expect-error Creating unknown component
+          TestComponent: new UnsupportedComponent({
+            hash: 1337,
+            name: 'TestComponent',
+            rawData: '1111011100110001000' as BinaryString,
+            version: 1
+          })
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      entity.removeComponent(1337);
+
+      expect(entity.components).toStrictEqual({
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an unknown component name', () => {
+    it('removes all matching components from the entity', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+          Unknown: [
+            new UnsupportedComponent({
+              hash: 1337,
+              name: 'TestComponent',
+              rawData: '1111011100110001000' as BinaryString,
+              version: 1
+            })
+          ]
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      entity.removeComponent('TestComponent');
+
+      expect(entity.components).toStrictEqual({
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 }),
+        Unknown: []
+      });
+    });
+  });
+});
+
+describe('Entity.setMaterial()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => entity.setMaterial();
+      const expectedError = new Error('You must pass a PhysicalMaterialPartHash to set as the material.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given a material hash', () => {
+    it('sets the given material', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+      entity.setMaterial(PhysicalMaterialPartHash.EvinonSteelAlloy);
+      const materialHash = entity.getMaterial();
+
+      expect(materialHash).toStrictEqual(31502);
+    });
+  });
+
+  describe('when given a material name', () => {
+    it('sets the given material', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+
+      entity.setMaterial('EvinonSteelAlloy');
+      const materialHash = entity.getMaterial();
+
+      expect(materialHash).toStrictEqual(31502);
+    });
+  });
+
+  describe('when the entity already has a PhysicalMaterialPart component', () => {
+    it('sets the given material', () => {
+      const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968', {
+        components: {
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({
+            version: 1,
+            materialHash: PhysicalMaterialPartHash.Gold
+          })
+        }
+      });
+
+      entity.setMaterial(PhysicalMaterialPartHash.EvinonSteelAlloy);
+      const materialHash = entity.getMaterial();
+
+      expect(materialHash).toStrictEqual(31502);
+    });
+  });
+});
+
+describe('Entity.toBinary()', () => {
+  it('returns a BinaryString representation of the entity', () => {
+    const prefabName = 'Torch';
+    const entityHash = 30100;
+    const entityName = 'Fire';
+    const entityIsAlive = true;
+    const componentHash = ComponentHash.HeatSourceBase;
+    const componentVersion = 1;
+
+    const entity = new Entity<typeof prefabName>(`${entityName}_${entityHash}`, {
+      hash: entityHash,
+      isAlive: entityIsAlive,
+      components: {
+        HeatSourceBase: new HeatSourceBaseComponent({
+          version: componentVersion,
+          isLit: true,
+          progress: 0.69
+        })
+      }
+    });
+
+    const data = entity.toBinary(new Map([[componentHash, componentVersion]]));
+
+    const expectedData =
+      '11111010011101111110111101000000000000000000000000000000001100001100111111001100001010001111010111010100011111011011000000000000000000000001110000000111010111100000000000000000000000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('Entity.write()', () => {
+  it('writes a BinaryString representation of the entity to the given BinaryWriter, including entity hash and data length', () => {
+    const prefabName = 'Torch';
+    const entityHash = 30100;
+    const entityName = 'Fire';
+    const entityIsAlive = true;
+
+    const entity = new Entity<typeof prefabName>(`${entityName}_${entityHash}`, {
+      hash: entityHash,
+      isAlive: entityIsAlive
+    });
+
+    const writer = new BinaryWriter();
+    entity.write(writer, new Map());
+
+    const data = writer.flush();
+
+    const expectedData =
+      '0000000000000000011101011001010000000000000000000000000000100001100000000000000000000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // Entity data length.
+    const isAliveBit = reader.readBoolean();
+
+    expect(hash).toStrictEqual(entityHash);
+    expect(isAliveBit).toStrictEqual(entityIsAlive);
+  });
+});
diff --git a/src/Entity.ts b/src/Entity.ts
new file mode 100644
index 0000000..fcb3542
--- /dev/null
+++ b/src/Entity.ts
@@ -0,0 +1,383 @@
+import type { BinaryReader } from './BinaryReader.js';
+import type { Component } from './components/Component.js';
+import type { ATTPrefabName } from './types/ATTPrefabName.js';
+import type { BinaryString } from './types/BinaryString.js';
+import type { EntityKey } from './types/EntityKey.js';
+import type { PrefabComponents } from './types/PrefabComponents.js';
+import type { SupportedPrefabComponents } from './types/SupportedPrefabComponents.js';
+import type { UnknownPrefabComponents } from './types/UnknownPrefabComponents.js';
+import type { UnsupportedPrefabComponents } from './types/UnsupportedPrefabComponents.js';
+
+import { BinaryWriter } from './BinaryWriter.js';
+import { FALLBACK_PHYSICAL_MATERIAL_PART_VERSION } from './Prefab.js';
+import { PhysicalMaterialPartComponent } from './components/PhysicalMaterialPartComponent.js';
+import { ATTPrefabs } from './types/ATTPrefabs.js';
+import { ComponentHash } from './types/ComponentHash.js';
+import { PhysicalMaterialPartHash } from './types/PhysicalMaterialPartHash.js';
+import { readComponents } from './utils/readComponents.js';
+import { writeComponents } from './utils/writeComponents.js';
+
+export type EntityProps = {
+  hash?: number | undefined;
+  isAlive?: boolean | undefined;
+  components?: (SupportedPrefabComponents & UnsupportedPrefabComponents & Partial<UnknownPrefabComponents>) | undefined;
+};
+
+type EntityFromBinaryProps = {
+  key: string;
+  hash: number;
+  componentVersions?: Map<number, number> | undefined;
+};
+
+/**
+ * An "item" inside a prefab composition. The `Entity` can have its own components to alter its
+ * behaviour. A child prefab of the composition may attach to an `Entity`, forming an hierarchical
+ * structure inside the composition. This is primarily used in _A Township Tale_'s crafting system.
+ *
+ * @see [Class: `Entity`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/Entity.md)
+ * @since v3.0.0
+ *
+ * @example
+ * import { Entity } from 'att-string-transcoder';
+ *
+ * const torchFireEntity = new Entity<'Torch'>('Fire_30100');
+ * // or
+ * const torchFireEntity = Entity.fromBinary<'Torch'>(myBinaryString);
+ */
+export class Entity<TPrefabName extends ATTPrefabName> {
+  /**
+   * The hash of the entity.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Torch'>('Fire_30100');
+   *
+   * const hash = entity.hash;
+   * // `hash` is `30100`
+   */
+  hash: number;
+
+  /**
+   * The name of the entity.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Torch'>('Fire_30100');
+   *
+   * const name = entity.name;
+   * // `name` is `'Fire'`
+   */
+  name: string;
+
+  /**
+   * The alive state of the entity.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Torch'>('Fire_30100');
+   *
+   * const isAlive = entity.isAlive;
+   * // `isAlive` is `true`
+   */
+  isAlive: boolean;
+
+  /**
+   * A map of the stored components.
+   *
+   * Provides access to the components stored in this entity. Components are keyed to their
+   * respective names, unless its data contained an unrecognised hash. In that case, the component
+   * will be stored in an array under the `Unknown` key.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Torch'>('Fire_30100');
+   *
+   * const components = entity.components;
+   * // `components` is `{ Unknown: [] }`
+   */
+  components: PrefabComponents;
+
+  /**
+   * Creates a new `Entity` object configured with the passed in configuration.
+   *
+   * @see [Class: `Entity`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/Entity.md)
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const torchFireEntity = new Entity<'Torch'>('Fire_30100', {
+   *   hash: 30100,
+   *   isAlive: true,
+   *   components: {}
+   * });
+   */
+  constructor(key: EntityKey<TPrefabName>, { hash, isAlive, components }: EntityProps = {}) {
+    const resolvedName = key === 'Unknown' ? String(key) : String(key).split('_').slice(0, -1).join('_');
+    const resolvedHash = resolvedName === 'Unknown' ? hash : Number(String(key).split('_').slice(-1));
+
+    if (typeof resolvedHash === 'undefined') {
+      throw new Error('You must manually pass an entity hash when instantiating an "Unknown" Entity.');
+    }
+
+    this.hash = resolvedHash;
+    this.name = resolvedName;
+    this.isAlive = isAlive ?? true;
+    this.components = {
+      ...components,
+      Unknown: components?.Unknown ?? []
+    };
+  }
+
+  /**
+   * Adds a `Component` to the entity. Will override any existing component with that name.
+   *
+   * @since v3.1.0
+   *
+   * @example
+   * import { Entity, PhysicalMaterialPartComponent, PhysicalMaterialPartHash } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+   * const component = new PhysicalMaterialPartComponent({ version: 1, materialHash: PhysicalMaterialPartHash.Iron });
+   *
+   * entity.addComponent(component);
+   */
+  addComponent(component: Component): this {
+    this.components = {
+      ...this.components,
+      [component.name]: component
+    };
+
+    return this;
+  }
+
+  /**
+   * Reads the binary string data and returns an instantiated entity.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const torchFireEntity = Entity.fromBinary<'Torch'>(binaryReader, { key, hash });
+   */
+  static fromBinary<TPrefabName extends ATTPrefabName>(
+    reader: BinaryReader,
+    { key, hash, componentVersions }: EntityFromBinaryProps
+  ): Entity<TPrefabName> {
+    const isAlive = reader.readBoolean();
+    const components = readComponents(reader, componentVersions);
+
+    return new Entity(key as keyof (typeof ATTPrefabs)[ATTPrefabName]['embedded'], {
+      hash,
+      isAlive,
+      components
+    });
+  }
+
+  /**
+   * Gets the entity's physical material.
+   *
+   * @since v3.1.0
+   *
+   * @example
+   * import { Entity, PhysicalMaterialPartHash } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+   *
+   * const materialHash = entity.getMaterial();
+   * const materialName = PhysicalMaterialPartHash[materialHash];
+   */
+  getMaterial(): PhysicalMaterialPartHash {
+    return this.components.PhysicalMaterialPart?.materialHash ?? 0;
+  }
+
+  /**
+   * Removes all components on this entity.
+   *
+   * @since v3.1.0
+   *
+   * @example
+   * import { Entity } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+   *
+   * entity.removeAllComponents();
+   */
+  removeAllComponents(): this {
+    this.components = { Unknown: [] };
+
+    return this;
+  }
+
+  /**
+   * Removes the specified component from this entity.
+   *
+   * @since v3.1.0
+   *
+   * @example
+   * import { ComponentHash, Entity } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+   *
+   * entity.removeComponent(ComponentHash.NetworkRigidbody);
+   * // or
+   * entity.removeComponent('NetworkRigidbody');
+   */
+  removeComponent(componentHash: ComponentHash): this;
+  removeComponent(componentName: keyof Omit<PrefabComponents, 'Unknown'>): this;
+  removeComponent(componentArg: ComponentHash | keyof Omit<PrefabComponents, 'Unknown'>): this {
+    if (typeof componentArg === 'undefined') {
+      throw new Error('You must pass a component hash or name to remove from this entity.');
+    }
+
+    const componentName =
+      typeof componentArg === 'string'
+        ? componentArg
+        : (ComponentHash[componentArg] as keyof typeof ComponentHash | undefined);
+
+    if (typeof componentName === 'undefined') {
+      for (const component of Object.values(this.components)) {
+        if (Array.isArray(component)) {
+          this.components.Unknown = component.filter(unknownComponent => unknownComponent.hash !== componentArg);
+        } else if (component.hash === componentArg) {
+          delete this.components[component.name as keyof Omit<PrefabComponents, 'Unknown'>];
+        }
+      }
+    } else {
+      if (componentName in this.components) {
+        delete this.components[componentName];
+      } else {
+        const unknownComponentIndex = this.components.Unknown.findIndex(component => component.name === componentArg);
+
+        if (unknownComponentIndex > -1) {
+          this.components.Unknown = this.components.Unknown.toSpliced(unknownComponentIndex, 1);
+        }
+      }
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the entity's physical material. This can change both its appearance and other qualities such
+   * as durability, damage, heat retention and weight.
+   *
+   * @since v3.1.0
+   *
+   * @example
+   * import { Entity, PhysicalMaterialPartHash } from 'att-string-transcoder';
+   *
+   * const entity = new Entity<'Standard_Side_Pouch_Attachment'>('standard_sidePouch_backPin_L1_7968');
+   *
+   * entity.setMaterial(PhysicalMaterialPartHash.Mythril);
+   * // or
+   * entity.setMaterial('Mythril');
+   */
+  setMaterial(materialHash: PhysicalMaterialPartHash): this;
+  setMaterial(materialName: keyof typeof PhysicalMaterialPartHash): this;
+  setMaterial(materialArg: PhysicalMaterialPartHash | keyof typeof PhysicalMaterialPartHash): this {
+    if (typeof materialArg === 'undefined') {
+      throw new Error('You must pass a PhysicalMaterialPartHash to set as the material.');
+    }
+
+    const version = this.components.PhysicalMaterialPart?.version ?? FALLBACK_PHYSICAL_MATERIAL_PART_VERSION;
+    const materialHash = typeof materialArg === 'number' ? materialArg : PhysicalMaterialPartHash[materialArg];
+
+    this.components.PhysicalMaterialPart = new PhysicalMaterialPartComponent({
+      ...this.components.PhysicalMaterialPart,
+      version,
+      materialHash
+    });
+
+    return this;
+  }
+
+  /**
+   * Returns a `BinaryString` representation of the entity.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { ComponentHash, Entity } from 'att-string-transcoder';
+   *
+   * const torchFireEntity = new Entity<'Torch'>('Fire_30100');
+   *
+   * const componentVersions = new Map<number, number>([
+   *   [ComponentHash.NetworkRigidbody, 1],
+   *   [ComponentHash.PhysicalMaterialPart, 1],
+   *   [ComponentHash.Pickup, 2]
+   *   // etc...
+   * ]);
+   *
+   * const binaryString = torchFireEntity.toBinary(componentVersions);
+   */
+  toBinary(componentVersions: Map<number, number>): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} isAlive
+     */
+    writer.writeBoolean(this.isAlive);
+
+    /**
+     * @property {PrefabComponents} components
+     */
+    writeComponents(writer, this.components, componentVersions);
+
+    return writer.flush();
+  }
+
+  /**
+   * Writes a `BinaryString` representation of the entity to the given `BinaryWriter`, including the
+   * entity hash and data length.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryWriter, ComponentHash, Entity } from 'att-string-transcoder';
+   *
+   * const torchFireEntity = new Entity<'Torch'>('Fire_30100');
+   *
+   * const componentVersions = new Map<number, number>([
+   *   [ComponentHash.NetworkRigidbody, 1],
+   *   [ComponentHash.PhysicalMaterialPart, 1],
+   *   [ComponentHash.Pickup, 2]
+   *   // etc...
+   * ]);
+   *
+   * const writer = new BinaryWriter();
+   *
+   * torchFireEntity.write(writer, componentVersions);
+   */
+  write(writer: BinaryWriter, componentVersions: Map<number, number>): void {
+    const data = this.toBinary(componentVersions);
+
+    /**
+     * @property {number} hash
+     */
+    writer.writeUnsignedInteger(this.hash);
+
+    /**
+     * @property {number} dataLength
+     */
+    writer.writeUnsignedInteger(data.length);
+
+    /**
+     * @property {BinaryString} data
+     */
+    writer.writeBits(data);
+  }
+}
diff --git a/src/Prefab.test.ts b/src/Prefab.test.ts
new file mode 100644
index 0000000..02bc4c6
--- /dev/null
+++ b/src/Prefab.test.ts
@@ -0,0 +1,2223 @@
+import type { BinaryString } from './types/BinaryString.js';
+import type { SaveString } from './types/SaveString.js';
+
+import { vi } from 'vitest';
+
+import { BinaryReader } from './BinaryReader.js';
+import { Entity } from './Entity.js';
+import { Prefab } from './Prefab.js';
+import { DurabilityModuleComponent } from './components/DurabilityModuleComponent.js';
+import { HeatSourceBaseComponent } from './components/HeatSourceBaseComponent.js';
+import { LiquidContainerComponent } from './components/LiquidContainerComponent.js';
+import { NetworkRigidbodyComponent } from './components/NetworkRigidbodyComponent.js';
+import { PhysicalMaterialPartComponent } from './components/PhysicalMaterialPartComponent.js';
+import { PickupComponent } from './components/PickupComponent.js';
+import { PopulationSpawnAreaComponent } from './components/PopulationSpawnAreaComponent.js';
+import { SentGiftComponent } from './components/SentGiftComponent.js';
+import { SpawnAreaComponent } from './components/SpawnAreaComponent.js';
+import { UnsupportedComponent } from './components/UnsupportedComponent.js';
+import { ATTPrefabs } from './types/ATTPrefabs.js';
+import { ComponentHash } from './types/ComponentHash.js';
+import { PhysicalMaterialPartHash } from './types/PhysicalMaterialPartHash.js';
+import { PopulationDefinitionHash } from './types/PopulationDefinitionHash.js';
+
+describe('new Prefab()', () => {
+  describe('when given only a prefab name', () => {
+    it('returns an instance of the Prefab class', () => {
+      const prefab = new Prefab('Handle_Short');
+
+      expect(prefab.hash).toStrictEqual(ATTPrefabs.Handle_Short.hash);
+      expect(prefab.components).toStrictEqual({ Unknown: [] });
+      expect(prefab.entities).toStrictEqual({});
+      expect(prefab.children).toStrictEqual([]);
+    });
+  });
+
+  describe('when given additional constructor props', () => {
+    it('returns an instance of the Prefab class', () => {
+      const prefab = new Prefab('Torch', {
+        components: {
+          Pickup: new PickupComponent({ version: 2 })
+        },
+        entities: {
+          Fire_30100: new Entity('Fire_30100', { isAlive: true })
+        },
+        children: [{ parentHash: 0, prefab: new Prefab('Guard') }]
+      });
+
+      expect(prefab.hash).toStrictEqual(ATTPrefabs.Torch.hash);
+
+      expect(prefab.components).toEqual({
+        Pickup: {
+          hash: ComponentHash.Pickup,
+          name: 'Pickup',
+          version: 2,
+          dockedMemory: [],
+          lastInteractorPlayerId: 0
+        },
+        Unknown: []
+      });
+
+      expect(prefab.entities).toEqual({
+        Fire_30100: {
+          hash: ATTPrefabs.Torch.embedded.Fire_30100.hash,
+          name: 'Fire',
+          isAlive: true,
+          components: { Unknown: [] }
+        }
+      });
+
+      expect(prefab.children).toEqual([
+        {
+          parentHash: 0,
+          prefab: new Prefab('Guard', {
+            position: { x: 0, y: 0, z: 0 },
+            rotation: { x: 0, y: 0, z: 0, w: 1 },
+            scale: 1,
+            components: { Unknown: [] },
+            entities: {},
+            children: []
+          })
+        }
+      ]);
+    });
+  });
+});
+
+describe('Prefab.addChildPrefab()', () => {
+  let parent: Prefab<'Handle_Short'>;
+
+  beforeEach(() => {
+    parent = new Prefab('Handle_Short');
+  });
+
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => parent.addChildPrefab();
+      const expectedError = new Error(
+        'You must pass a parent prefab entity hash (or null) and a child prefab to add as a child to this prefab.'
+      );
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given a null parentKey', () => {
+    it('adds a child prefab attached to parentHash 0', () => {
+      const child = new Prefab('Guard');
+
+      parent.addChildPrefab(null, child);
+
+      expect(parent.children).toStrictEqual([
+        {
+          parentHash: 0,
+          prefab: child
+        }
+      ]);
+    });
+  });
+
+  describe('when given a valid parentKey', () => {
+    it('adds a child prefab attached to the corresponding entity', () => {
+      const child = new Prefab('Guard');
+
+      parent.addChildPrefab('Slot_Multi_6136', child);
+
+      expect(parent.children).toStrictEqual([
+        {
+          parentHash: 6136,
+          prefab: child
+        }
+      ]);
+    });
+  });
+
+  describe('when given an invalid parentKey', () => {
+    it('throws an error', () => {
+      const child = new Prefab('Guard');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => parent.addChildPrefab('Invalid_Entity_Name', child);
+      const expectedError = new Error('"Invalid_Entity_Name" is not a valid entity on "Handle_Short".');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('Prefab.addComponent()', () => {
+  let prefab: Prefab<'Handle_Short'>;
+
+  beforeEach(() => {
+    prefab = new Prefab('Handle_Short');
+  });
+
+  it('adds a component to the prefab', () => {
+    const component = new PickupComponent({ version: 2, lastInteractorPlayerId: 1337 });
+
+    prefab.addComponent(component);
+
+    expect(prefab.components).toStrictEqual({
+      Pickup: component,
+      Unknown: []
+    });
+  });
+});
+
+describe('Prefab.addEntity()', () => {
+  let prefab: Prefab<'Handle_Short'>;
+
+  beforeEach(() => {
+    prefab = new Prefab('Handle_Short');
+  });
+
+  it('adds an entity to the prefab', () => {
+    const entity = new Entity<'Handle_Short'>('Slot_Multi_6136');
+
+    prefab.addEntity(entity);
+
+    expect(prefab.entities).toStrictEqual({
+      Slot_Multi_6136: entity
+    });
+  });
+});
+
+describe('Prefab.addGift()', () => {
+  let prefab: Prefab<'Gift_Mail_Box'>;
+  let gift: Prefab<'Dynamite'>;
+
+  beforeEach(() => {
+    prefab = new Prefab('Gift_Mail_Box');
+    gift = new Prefab('Dynamite');
+  });
+
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.addGift();
+      const expectedError = new Error('You must pass a gift prefab to add to this prefab as a gift.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given required arguments', () => {
+    it('adds a gift to the prefab', () => {
+      prefab.addGift(gift);
+
+      const unsignedIntegers = [31326, 0, 0, 0, 0, 0, 0, 1065353216, 1065353216, 0, 0, 0, 0];
+      const hash = 31326;
+      const bytes = 48;
+      const chunkVersioning = [] as number[];
+
+      expect(gift.hash).toStrictEqual(hash);
+      expect(prefab.components.SentGift).toBeInstanceOf(SentGiftComponent);
+      expect(prefab.components.SentGift?.gifts.length).toStrictEqual(1);
+      expect(prefab.components.SentGift?.gifts[0]).toStrictEqual({
+        data: unsignedIntegers,
+        messageSizeInBytes: bytes,
+        hash,
+        chunkVersioning
+      });
+    });
+
+    it('adds an additional gift to the prefab', () => {
+      prefab.addGift(gift);
+      prefab.addGift(gift);
+
+      const unsignedIntegers = [31326, 0, 0, 0, 0, 0, 0, 1065353216, 1065353216, 0, 0, 0, 0];
+      const hash = 31326;
+      const bytes = 48;
+      const chunkVersioning = [] as number[];
+
+      expect(gift.hash).toStrictEqual(hash);
+      expect(prefab.components.SentGift).toBeInstanceOf(SentGiftComponent);
+      expect(prefab.components.SentGift?.gifts.length).toStrictEqual(2);
+      expect(prefab.components.SentGift?.gifts[0]).toStrictEqual({
+        data: unsignedIntegers,
+        messageSizeInBytes: bytes,
+        hash,
+        chunkVersioning
+      });
+      expect(prefab.components.SentGift?.gifts[1]).toStrictEqual({
+        data: unsignedIntegers,
+        messageSizeInBytes: bytes,
+        hash,
+        chunkVersioning
+      });
+    });
+  });
+
+  describe('when the gift prefab SaveString contains no data', () => {
+    it('throws an error', () => {
+      const spy = vi.spyOn(gift, 'toSaveString');
+      spy.mockImplementationOnce(() => '|' as SaveString);
+
+      const expectedToThrow = () => prefab.addGift(gift);
+      const expectedError = new Error('Gift prefab data is corrupted.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the gift prefab SaveString contains malformed data', () => {
+    it('throws an error', () => {
+      const spy = vi.spyOn(gift, 'toSaveString');
+      spy.mockImplementationOnce(() => ',|,,' as SaveString);
+
+      const expectedToThrow = () => prefab.addGift(gift);
+      const expectedError = new Error('Gift prefab data is corrupted.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('Prefab.clone()', () => {
+  it('returns a deep clone of the prefab', () => {
+    const original = new Prefab('Guard').setMaterial('Mythril');
+    const clone = original.clone();
+
+    clone.setMaterial('Gold');
+
+    expect(original.getMaterial()).toStrictEqual(PhysicalMaterialPartHash.Mythril);
+    expect(clone.getMaterial()).toStrictEqual(PhysicalMaterialPartHash.Gold);
+  });
+});
+
+describe('Prefab.fromBinary()', () => {
+  let reader: BinaryReader;
+  const componentVersions = new Map([[1454441398, 2]]);
+  const prefab = new Prefab('Handle_Short', {
+    components: {
+      Pickup: new PickupComponent({ version: 2 })
+    }
+  });
+
+  beforeEach(() => {
+    const binaryString =
+      '0000000000000000101001001111011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000001111111000000000000000000000000101011010110001000000111011011000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' as BinaryString;
+    reader = new BinaryReader(binaryString);
+  });
+
+  describe('when given required arguments', () => {
+    it('creates an instance of the Prefab class using the given BinaryReader', () => {
+      const prefabFromBinary = Prefab.fromBinary(reader);
+
+      expect(prefabFromBinary).toStrictEqual(prefab);
+    });
+  });
+
+  describe('when given optional arguments', () => {
+    it('creates an instance of the Prefab class using the given BinaryReader', () => {
+      const prefabFromBinary = Prefab.fromBinary(reader, componentVersions);
+
+      expect(prefabFromBinary).toStrictEqual(prefab);
+    });
+  });
+
+  describe('when given binary data containing an invalid prefab hash', () => {
+    it('throws an error', () => {
+      const readerWithInvalidData = new BinaryReader(
+        '1111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000001111111000000000000000000000000101011010110001000000111011011000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
+      );
+
+      const expectedToThrow = () => Prefab.fromBinary(readerWithInvalidData);
+      const expectedError = new Error('Cannot find ATT Prefab with hash 4294967295.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('Prefab.fromSaveString()', () => {
+  let saveString: SaveString;
+  const prefab = new Prefab('Handle_Short');
+
+  beforeEach(() => {
+    saveString = '42230,48,42230,0,0,0,0,0,0,1065353216,1065353216,0,0,0,' as SaveString;
+  });
+
+  describe('when the SaveString contains no component versions', () => {
+    it('creates an instance of the Prefab class using the given SaveString', () => {
+      const prefabFromSaveString = Prefab.fromSaveString(saveString);
+
+      expect(prefabFromSaveString).toStrictEqual(prefab);
+    });
+  });
+
+  describe('when the SaveString contains component versions', () => {
+    beforeEach(() => {
+      saveString = `${saveString}|3,2290978823,1,1454441398,2,4109360768,1,` as SaveString;
+    });
+
+    it('creates an instance of the Prefab class using the given SaveString', () => {
+      const prefabFromSaveString = Prefab.fromSaveString(saveString);
+
+      expect(prefabFromSaveString).toStrictEqual(prefab);
+    });
+  });
+
+  describe('when the SaveString contains incorrect component versions length', () => {
+    beforeEach(() => {
+      saveString = `${saveString}|69,2290978823,1,1454441398,2,4109360768,1,` as SaveString;
+    });
+
+    it('throws an error', () => {
+      const expectedToThrow = () => Prefab.fromSaveString(saveString);
+      const expectedError = new Error('SaveString contains invalid versioning. Expected 69 versions but parsed 3.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the SaveString contains malformed component versions', () => {
+    beforeEach(() => {
+      saveString = `${saveString}|,,,` as SaveString;
+    });
+
+    it('throws an error', () => {
+      const expectedToThrow = () => Prefab.fromSaveString(saveString);
+      const expectedError = new Error('SaveString is malformed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the SaveString contains no data', () => {
+    beforeEach(() => {
+      saveString = `|,` as SaveString;
+    });
+
+    it('throws an error', () => {
+      const expectedToThrow = () => Prefab.fromSaveString(saveString);
+      const expectedError = new Error('SaveString is malformed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the SaveString contains malformed data', () => {
+    beforeEach(() => {
+      saveString = `0,0,` as SaveString;
+    });
+
+    it('throws an error', () => {
+      const expectedToThrow = () => Prefab.fromSaveString(saveString);
+      const expectedError = new Error('SaveString is malformed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the passed argument is not a valid SaveString', () => {
+    beforeEach(() => {
+      saveString = `0` as SaveString;
+    });
+
+    it('throws an error', () => {
+      const expectedToThrow = () => Prefab.fromSaveString(saveString);
+      const expectedError = new Error('SaveString is malformed.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('Prefab.getAngularVelocity()', () => {
+  describe('when the prefab has no NetworkRigidBody component', () => {
+    it('returns an angular velocity of zero', () => {
+      const prefab = new Prefab('Handle_Short');
+      delete prefab.components.NetworkRigidbody;
+
+      const angularVelocity = prefab.getAngularVelocity();
+
+      expect(angularVelocity).toStrictEqual({ x: 0, y: 0, z: 0 });
+    });
+  });
+
+  describe('when the prefab has a NetworkRigidBody component with angular velocity', () => {
+    it('returns the stored angular velocity', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            angularVelocity: { x: 69, y: 420, z: 1337 }
+          })
+        }
+      });
+
+      const angularVelocity = prefab.getAngularVelocity();
+
+      expect(angularVelocity).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+});
+
+describe('Prefab.getChildPrefab()', () => {
+  describe('when providing the name of an existing child prefab', () => {
+    it('returns the first matching child prefab', () => {
+      const prefab = new Prefab('Handle_Short');
+
+      prefab.addChildPrefab('Slot_Large_SwordType_Craft_6134', new Prefab('Guard'));
+      prefab.addChildPrefab('Slot_Large_SwordType_Craft_54356', new Prefab('Guard'));
+
+      const child = prefab.getChildPrefab('Guard');
+
+      expect(typeof child).not.toBeUndefined();
+      expect(child?.name).toStrictEqual('Guard');
+    });
+  });
+
+  describe('when providing the name of an existing child prefab and a parent hash', () => {
+    it('returns the first matching child prefab', () => {
+      const prefab = new Prefab('Handle_Short');
+
+      const goldGuard = new Prefab('Guard').setMaterial('Gold');
+      const mythrilGuard = new Prefab('Guard').setMaterial('Mythril');
+
+      prefab.addChildPrefab('Slot_Large_SwordType_Craft_6134', goldGuard);
+      prefab.addChildPrefab('Slot_Large_SwordType_Craft_54356', mythrilGuard);
+
+      const child = prefab.getChildPrefab('Guard', 54356);
+
+      expect(child).not.toBeUndefined();
+      expect(child?.name).toStrictEqual('Guard');
+      expect(child?.getMaterial()).toStrictEqual(PhysicalMaterialPartHash.Mythril);
+    });
+  });
+
+  describe('when providing the name of a non-existent child prefab', () => {
+    it('returns undefined', () => {
+      const prefab = new Prefab('Handle_Short');
+
+      prefab.addChildPrefab('Slot_Large_SwordType_Craft_6134', new Prefab('Guard'));
+      prefab.addChildPrefab('Slot_Large_SwordType_Craft_54356', new Prefab('Guard'));
+
+      const child = prefab.getChildPrefab('Pommel');
+
+      expect(child).toBeUndefined();
+    });
+  });
+});
+
+describe('Prefab.getComponentVersions()', () => {
+  describe('when given consistent component versions', () => {
+    it('returns a Map<number, number> of the versions of the components on a prefab', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 }),
+          Unknown: [
+            new UnsupportedComponent({
+              hash: 1337,
+              name: 'Unknown',
+              rawData: '1111011100110001000' as BinaryString,
+              version: 1
+            })
+          ]
+        },
+        entities: {
+          Fire_30100: new Entity('Fire_30100', {
+            components: {
+              HeatSourceBase: new HeatSourceBaseComponent({ version: 1 }),
+              Unknown: [
+                new UnsupportedComponent({
+                  hash: 1337,
+                  name: 'Unknown',
+                  rawData: '1111011100110001000' as BinaryString,
+                  version: 1
+                })
+              ]
+            }
+          })
+        },
+        children: [
+          {
+            parentHash: 0,
+            prefab: new Prefab('Guard', {
+              components: {
+                PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: 1 })
+              }
+            })
+          }
+        ]
+      });
+
+      const componentVersions = prefab.getComponentVersions();
+
+      expect(componentVersions).toStrictEqual(
+        new Map([
+          [2290978823, 1],
+          [1454441398, 2],
+          [1337, 1],
+          [4109360768, 1],
+          [272188517, 1]
+        ])
+      );
+    });
+  });
+
+  describe('when given inconsistent component versions', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          Unknown: [
+            new UnsupportedComponent({
+              hash: 1337,
+              name: 'Unknown',
+              rawData: '1111011100110001000' as BinaryString,
+              version: 420
+            })
+          ]
+        },
+        entities: {
+          Fire_30100: new Entity('Fire_30100', {
+            components: {
+              Unknown: [
+                new UnsupportedComponent({
+                  hash: 1337,
+                  name: 'Unknown',
+                  rawData: '1111011100110001000' as BinaryString,
+                  version: 69
+                })
+              ]
+            }
+          })
+        }
+      });
+
+      const expectedToThrow = () => prefab.getComponentVersions();
+      const expectedError = new Error(
+        'Component 1337 exists with version 420 and 69. All instances of a component must exist with the same version.'
+      );
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+});
+
+describe('Prefab.getGiftBoxLabel', () => {
+  describe('when the prefab has no SentGift component', () => {
+    it('returns an empty string', () => {
+      const prefab = new Prefab('Gift_Mail_Box');
+      delete prefab.components.SentGift;
+
+      const giftBoxLabel = prefab.getGiftBoxLabel();
+
+      expect(giftBoxLabel).toStrictEqual('');
+    });
+  });
+
+  describe('when the prefab has a SentGift component with senderName', () => {
+    it('returns the stored gift box label', () => {
+      const prefab = new Prefab('Gift_Mail_Box', {
+        components: {
+          SentGift: new SentGiftComponent({
+            version: 1,
+            senderName: 'topkek'
+          })
+        }
+      });
+
+      const giftBoxLabel = prefab.getGiftBoxLabel();
+
+      expect(giftBoxLabel).toStrictEqual('topkek');
+    });
+  });
+});
+
+describe('Prefab.getIntegrity()', () => {
+  describe('when the prefab has no DurabilityModule component', () => {
+    it('returns full integrity', () => {
+      const prefab = new Prefab('Short_Sword_Blade');
+      delete prefab.components.DurabilityModule;
+
+      const integrity = prefab.getIntegrity();
+
+      expect(integrity).toStrictEqual(1);
+    });
+  });
+
+  describe('when the prefab has a DurabilityModule component with integrity', () => {
+    it('returns the stored integrity', () => {
+      const prefab = new Prefab('Short_Sword_Blade', {
+        components: {
+          DurabilityModule: new DurabilityModuleComponent({
+            version: 1,
+            integrity: 0.69
+          })
+        }
+      });
+
+      const integrity = prefab.getIntegrity();
+
+      expect(integrity).toBeCloseTo(0.69, 2);
+    });
+  });
+});
+
+describe('Prefab.getKinematic()', () => {
+  describe('when the prefab has no NetworkRigidbody component', () => {
+    it('returns isKinematic of false', () => {
+      const prefab = new Prefab('Handle_Short');
+      delete prefab.components.NetworkRigidbody;
+
+      const isKinematic = prefab.getKinematic();
+
+      expect(isKinematic).toStrictEqual(false);
+    });
+  });
+
+  describe('when the prefab has a NetworkRigidbody component with isKinematic', () => {
+    it('returns the stored isKinematic', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            isKinematic: true
+          })
+        }
+      });
+
+      const isKinematic = prefab.getKinematic();
+
+      expect(isKinematic).toStrictEqual(true);
+    });
+  });
+});
+
+describe('Prefab.getMaterial()', () => {
+  describe('when the prefab has no PhysicalMaterialPart component', () => {
+    it('returns materialHash of zero', () => {
+      const prefab = new Prefab('Short_Sword_Blade');
+      delete prefab.components.PhysicalMaterialPart;
+
+      const materialHash = prefab.getMaterial();
+
+      expect(materialHash).toStrictEqual(0);
+    });
+  });
+
+  describe('when the prefab has a PhysicalMaterialPart component with materialHash', () => {
+    it('returns the stored isKinematic', () => {
+      const prefab = new Prefab('Short_Sword_Blade', {
+        components: {
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({
+            version: 1,
+            materialHash: PhysicalMaterialPartHash.EvinonSteelAlloy
+          })
+        }
+      });
+
+      const materialHash = prefab.getMaterial();
+
+      expect(materialHash).toStrictEqual(31502);
+    });
+  });
+});
+
+describe('Prefab.getOnFire()', () => {
+  describe('when the prefab has no entity with HeatSourceBase component', () => {
+    it('returns false', () => {
+      const prefab = new Prefab('Grass_Clump');
+      delete prefab.entities['Fire_30100']?.components.HeatSourceBase;
+
+      const isOnFire = prefab.getOnFire();
+
+      expect(isOnFire).toStrictEqual(false);
+    });
+  });
+
+  describe('when the prefab has an entity with HeatSourceBase component with isLit', () => {
+    it('returns the stored isLit', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        entities: {
+          Fire_30100: new Entity('Fire_30100', {
+            components: {
+              HeatSourceBase: new HeatSourceBaseComponent({
+                version: 1,
+                isLit: true
+              })
+            }
+          })
+        }
+      });
+
+      const isOnFire = prefab.getOnFire();
+
+      expect(isOnFire).toStrictEqual(true);
+    });
+  });
+});
+
+describe('Prefab.getPosition()', () => {
+  it('returns the Position of the Prefab', () => {
+    const prefab = new Prefab('Handle_Short', { position: { x: 69, y: 420, z: 1337 } });
+
+    const position = prefab.getPosition();
+
+    expect(position).toStrictEqual({ x: 69, y: 420, z: 1337 });
+  });
+});
+
+describe('Prefab.getRotation()', () => {
+  it('returns the Rotation of the Prefab', () => {
+    const prefab = new Prefab('Handle_Short', { rotation: { x: 0.69, y: 0.42, z: -0.1337, w: 0.88 } });
+
+    const rotation = prefab.getRotation();
+
+    expect(rotation).toStrictEqual({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+  });
+});
+
+describe('Prefab.getScale()', () => {
+  it('returns the scale of the Prefab', () => {
+    const prefab = new Prefab('Handle_Short', { scale: 0.69 });
+
+    const scale = prefab.getScale();
+
+    expect(scale).toBeCloseTo(0.69, 2);
+  });
+});
+
+describe('Prefab.getServerSleeping()', () => {
+  describe('when the prefab has no NetworkRigidbody component', () => {
+    it('returns isServerSleeping of false', () => {
+      const prefab = new Prefab('Handle_Short');
+      delete prefab.components.NetworkRigidbody;
+
+      const isServerSleeping = prefab.getServerSleeping();
+
+      expect(isServerSleeping).toStrictEqual(false);
+    });
+  });
+
+  describe('when the prefab has a NetworkRigidbody component with isServerSleeping', () => {
+    it('returns the stored isServerSleeping', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            isServerSleeping: true
+          })
+        }
+      });
+
+      const isServerSleeping = prefab.getServerSleeping();
+
+      expect(isServerSleeping).toStrictEqual(true);
+    });
+  });
+});
+
+describe('Prefab.getServings()', () => {
+  describe('when the prefab has no LiquidContainer component', () => {
+    it('returns a servings of zero', () => {
+      const prefab = new Prefab('Potion_Medium');
+      delete prefab.components.LiquidContainer;
+
+      const servings = prefab.getServings();
+
+      expect(servings).toStrictEqual(0);
+    });
+  });
+
+  describe('when the prefab has a LiquidContainer component with contentLevel', () => {
+    it('returns the stored contentLevel', () => {
+      const prefab = new Prefab('Potion_Medium', {
+        components: {
+          LiquidContainer: new LiquidContainerComponent({
+            version: 1,
+            contentLevel: 420
+          })
+        }
+      });
+
+      const servings = prefab.getServings();
+
+      expect(servings).toStrictEqual(420);
+    });
+  });
+});
+
+describe('Prefab.getSpawnAreaPopulationName()', () => {
+  describe('when the prefab has no PopulationSpawnArea component', () => {
+    it('returns undefined', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.PopulationSpawnArea;
+
+      const populationName = prefab.getSpawnAreaPopulationName();
+
+      expect(populationName).toStrictEqual(undefined);
+    });
+  });
+
+  describe('when the prefab has a PopulationSpawnArea component', () => {
+    describe('when the stored population definition is not recognised', () => {
+      it('returns a population definition name of "Unknown"', () => {
+        const prefab = new Prefab('Disk_Encounter', {
+          components: {
+            PopulationSpawnArea: new PopulationSpawnAreaComponent({
+              version: 2,
+              definition: 1337
+            })
+          }
+        });
+
+        const populationName = prefab.getSpawnAreaPopulationName();
+
+        expect(populationName).toStrictEqual('Unknown');
+      });
+    });
+
+    describe('when the stored population definition is recognised', () => {
+      it('returns the stored population definition name', () => {
+        const prefab = new Prefab('Disk_Encounter', {
+          components: {
+            PopulationSpawnArea: new PopulationSpawnAreaComponent({
+              version: 2,
+              definition: PopulationDefinitionHash.WyrmPopulation
+            })
+          }
+        });
+
+        const populationName = prefab.getSpawnAreaPopulationName();
+
+        expect(populationName).toStrictEqual('WyrmPopulation');
+      });
+    });
+  });
+});
+
+describe('Prefab.getVelocity()', () => {
+  describe('when the prefab has no NetworkRigidBody component', () => {
+    it('returns a velocity of zero', () => {
+      const prefab = new Prefab('Handle_Short');
+      delete prefab.components.NetworkRigidbody;
+
+      const velocity = prefab.getVelocity();
+
+      expect(velocity).toStrictEqual({ x: 0, y: 0, z: 0 });
+    });
+  });
+
+  describe('when the prefab has a NetworkRigidBody component with angular velocity', () => {
+    it('returns the stored velocity', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            velocity: { x: 69, y: 420, z: 1337 }
+          })
+        }
+      });
+
+      const velocity = prefab.getVelocity();
+
+      expect(velocity).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+});
+
+describe('Prefab.inspect()', () => {
+  it('prints the internal data structure of the prefab to the stdout', () => {
+    const spy = vi.spyOn(process.stdout, 'write');
+    spy.mockImplementationOnce(() => true);
+
+    const prefab = new Prefab('Handle_Short');
+    prefab.inspect();
+
+    expect(spy).toHaveBeenCalledWith(`Prefab {
+  name: 'Handle_Short',
+  hash: 42230,
+  position: { x: 0, y: 0, z: 0 },
+  rotation: { x: 0, y: 0, z: 0, w: 1 },
+  scale: 1,
+  components: { Unknown: [] },
+  entities: {},
+  children: []
+}\n`);
+  });
+});
+
+describe('Prefab.print()', () => {
+  it('prints the SaveString of the prefab to the stdout', () => {
+    const spy = vi.spyOn(process.stdout, 'write');
+    spy.mockImplementationOnce(() => true);
+
+    const prefab = new Prefab('Handle_Short');
+    prefab.print();
+
+    expect(spy).toHaveBeenCalledWith('42230,48,42230,0,0,0,0,0,0,1065353216,1065353216,0,0,0,\n');
+  });
+});
+
+describe('Prefab.removeAllChildPrefabs()', () => {
+  it('removes all child prefabs from the Prefab', () => {
+    const prefab = new Prefab('Handle_Short', {
+      children: [
+        { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+        { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+        { parentHash: 0, prefab: new Prefab('Phantom_Guard') }
+      ]
+    });
+
+    prefab.removeAllChildPrefabs();
+
+    expect(prefab.children).toStrictEqual([]);
+  });
+});
+
+describe('Prefab.removeAllComponents()', () => {
+  it('removes all components from the Prefab', () => {
+    const prefab = new Prefab('Handle_Short', {
+      components: {
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        Pickup: new PickupComponent({ version: 2 }),
+        Unknown: [
+          new UnsupportedComponent({
+            hash: 1337,
+            name: 'Unknown',
+            rawData: '1111011100110001000' as BinaryString,
+            version: 1
+          })
+        ]
+      }
+    });
+
+    prefab.removeAllComponents();
+
+    expect(prefab.components).toStrictEqual({ Unknown: [] });
+  });
+});
+
+describe('Prefab.removeAllEntities()', () => {
+  it('removes all entities from the Prefab', () => {
+    const prefab = new Prefab('Grass_Clump', {
+      entities: {
+        Fire_30100: new Entity('Fire_30100', {
+          components: {
+            Unknown: [
+              new UnsupportedComponent({
+                hash: 1337,
+                name: 'Unknown',
+                rawData: '1111011100110001000' as BinaryString,
+                version: 69
+              })
+            ]
+          }
+        }),
+        /* @ts-expect-error Add in an unknown entity. */
+        Unknown_1337: new Entity('Unknown', { hash: 1337 })
+      }
+    });
+
+    prefab.removeAllEntities();
+
+    expect(prefab.entities).toStrictEqual({});
+  });
+});
+
+describe('Prefab.removeAllGifts()', () => {
+  it('removes all gift `Prefab` from the Prefab', () => {
+    const prefab = new Prefab('Gift_Mail_Box')
+      .addGift(new Prefab('Dynamite'))
+      .addGift(new Prefab('Dynamite'))
+      .addGift(new Prefab('Dynamite'));
+
+    expect(prefab.components.SentGift?.gifts.length).toStrictEqual(3);
+
+    prefab.removeAllGifts();
+
+    expect(prefab.components.SentGift?.gifts.length).toStrictEqual(0);
+  });
+});
+
+describe('Prefab.removeChildPrefab()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Handle_Short', {
+        children: [
+          { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+          { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+          { parentHash: 0, prefab: new Prefab('Guard') },
+          { parentHash: 0, prefab: new Prefab('Guard') }
+        ]
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.removeChildPrefab();
+      const expectedError = new Error('You must pass a child prefab hash or name to remove from this prefab.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given a child prefab hash', () => {
+    it('removes all matching children from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        children: [
+          { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+          { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+          { parentHash: 0, prefab: new Prefab('Guard') },
+          { parentHash: 0, prefab: new Prefab('Guard') }
+        ]
+      });
+
+      prefab.removeChildPrefab(6940);
+
+      expect(prefab.children).toStrictEqual([
+        { parentHash: 0, prefab: new Prefab('Guard') },
+        { parentHash: 0, prefab: new Prefab('Guard') }
+      ]);
+    });
+  });
+
+  describe('when given a child prefab name', () => {
+    it('removes all matching children from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        children: [
+          { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+          { parentHash: 0, prefab: new Prefab('Phantom_Guard') },
+          { parentHash: 0, prefab: new Prefab('Guard') },
+          { parentHash: 0, prefab: new Prefab('Guard') }
+        ]
+      });
+
+      prefab.removeChildPrefab('Phantom_Guard');
+
+      expect(prefab.children).toStrictEqual([
+        { parentHash: 0, prefab: new Prefab('Guard') },
+        { parentHash: 0, prefab: new Prefab('Guard') }
+      ]);
+    });
+  });
+});
+
+describe('Prefab.removeComponent()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 })
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.removeComponent();
+      const expectedError = new Error('You must pass a component hash or name to remove from this prefab.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given a valid component hash', () => {
+    it('removes all matching components from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 })
+        }
+      });
+
+      prefab.removeComponent(2290978823);
+
+      expect(prefab.components).toStrictEqual({
+        Pickup: new PickupComponent({ version: 2 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given a valid component name', () => {
+    it('removes all matching components from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 })
+        }
+      });
+
+      prefab.removeComponent('NetworkRigidbody');
+
+      expect(prefab.components).toStrictEqual({
+        Pickup: new PickupComponent({ version: 2 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an invalid component hash', () => {
+    it('removes zero components from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 })
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      prefab.removeComponent(0);
+
+      expect(prefab.components).toStrictEqual({
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        Pickup: new PickupComponent({ version: 2 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an unknown component hash', () => {
+    it('removes all matching components from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 }),
+          // @ts-expect-error Creating unknown component
+          TestComponent: new UnsupportedComponent({
+            hash: 1337,
+            name: 'TestComponent',
+            rawData: '1111011100110001000' as BinaryString,
+            version: 1
+          })
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      prefab.removeComponent(1337);
+
+      expect(prefab.components).toStrictEqual({
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        Pickup: new PickupComponent({ version: 2 }),
+        Unknown: []
+      });
+    });
+  });
+
+  describe('when given an unknown component name', () => {
+    it('removes all matching components from the Prefab', () => {
+      const prefab = new Prefab('Handle_Short', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 }),
+          Unknown: [
+            new UnsupportedComponent({
+              hash: 1337,
+              name: 'TestComponent',
+              rawData: '1111011100110001000' as BinaryString,
+              version: 1
+            })
+          ]
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      prefab.removeComponent('TestComponent');
+
+      expect(prefab.components).toStrictEqual({
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        Pickup: new PickupComponent({ version: 2 }),
+        Unknown: []
+      });
+    });
+  });
+});
+
+describe('Prefab.removeEntity()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        entities: {
+          Fire_30100: new Entity('Fire_30100'),
+          Insert_Grass_7796: new Entity('Insert_Grass_7796')
+        }
+      });
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.removeEntity();
+      const expectedError = new Error('You must pass an entity name to remove from this prefab.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given an entity name', () => {
+    it('removes all matching entities from the Prefab', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        entities: {
+          Fire_30100: new Entity('Fire_30100'),
+          Insert_Grass_7796: new Entity('Insert_Grass_7796')
+        }
+      });
+
+      prefab.removeEntity('Insert_Grass_7796');
+
+      expect(prefab.entities).toStrictEqual({
+        Fire_30100: new Entity<'Grass_Clump'>('Fire_30100')
+      });
+    });
+  });
+});
+
+describe('Prefab.removeGift()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Gift_Mail_Box')
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Firework'));
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.removeGift();
+      const expectedError = new Error('You must pass a gift prefab hash or name to remove from this prefab.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when given a gift prefab hash', () => {
+    it('removes all matching gifts from the Prefab', () => {
+      const prefab = new Prefab('Gift_Mail_Box')
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Firework'));
+
+      prefab.removeGift(new Prefab('Dynamite').hash);
+
+      expect(prefab.components.SentGift?.gifts.length).toStrictEqual(1);
+    });
+  });
+
+  describe('when given a gift prefab name', () => {
+    it('removes all matching gifts from the Prefab', () => {
+      const prefab = new Prefab('Gift_Mail_Box')
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Firework'));
+
+      prefab.removeGift(new Prefab('Dynamite').name);
+
+      expect(prefab.components.SentGift?.gifts.length).toStrictEqual(1);
+    });
+  });
+
+  describe('when given an invalid gift prefab name', () => {
+    it('removes all matching gifts from the Prefab', () => {
+      const prefab = new Prefab('Gift_Mail_Box')
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Dynamite'))
+        .addGift(new Prefab('Firework'));
+
+      // @ts-expect-error Passing invalid arguments
+      prefab.removeGift('Invalid_Prefab_Name');
+
+      expect(prefab.components.SentGift?.gifts.length).toStrictEqual(3);
+    });
+  });
+});
+
+describe('Prefab.removeSpawnArea()', () => {
+  it('removes the spawn area components', () => {
+    const prefab = new Prefab('Disk_Encounter', {
+      components: {
+        PopulationSpawnArea: new PopulationSpawnAreaComponent({ version: 1 }),
+        SpawnArea: new SpawnAreaComponent({ version: 1 })
+      }
+    });
+
+    prefab.removeSpawnArea();
+
+    expect(prefab.components.PopulationSpawnArea).toStrictEqual(undefined);
+    expect(prefab.components.SpawnArea).toStrictEqual(undefined);
+  });
+});
+
+describe('Prefab.setAngularVelocity()', () => {
+  describe('when the prefab cannot have a NetworkRigidbody component', () => {
+    it('sets no angular velocity', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.NetworkRigidbody;
+
+      prefab.setAngularVelocity({ x: 69, y: 420, z: 1337 });
+      const angularVelocity = prefab.getAngularVelocity();
+
+      expect(angularVelocity).toStrictEqual({ x: 0, y: 0, z: 0 });
+    });
+  });
+
+  describe('when the prefab can have a NetworkRigidbody component', () => {
+    it('sets the given angular velocity', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setAngularVelocity({ x: 69, y: 420, z: 1337 });
+      const angularVelocity = prefab.getAngularVelocity();
+
+      expect(angularVelocity).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+
+  describe('when the prefab already has a NetworkRigidbody component', () => {
+    it('sets the given angular velocity', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            angularVelocity: { x: 88, y: -88, z: -88 }
+          })
+        }
+      });
+
+      prefab.setAngularVelocity({ x: 69, y: 420, z: 1337 });
+      const angularVelocity = prefab.getAngularVelocity();
+
+      expect(angularVelocity).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+});
+
+describe('Prefab.setGiftBoxLabel()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Gift_Mail_Box');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.setGiftBoxLabel();
+      const expectedError = new Error('You must pass a string to set as the gift box label.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the prefab cannot have a SentGift component', () => {
+    it('sets no gift box label', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.SentGift;
+
+      prefab.setGiftBoxLabel('topkek');
+      const giftBoxLabel = prefab.getGiftBoxLabel();
+
+      expect(giftBoxLabel).toStrictEqual('');
+    });
+  });
+
+  describe('when the prefab can have a SentGift component', () => {
+    it('sets the given gift box label', () => {
+      const prefab = new Prefab('Gift_Mail_Box');
+
+      prefab.setGiftBoxLabel('topkek');
+      const giftBoxLabel = prefab.getGiftBoxLabel();
+
+      expect(giftBoxLabel).toStrictEqual('topkek');
+    });
+  });
+
+  describe('when the prefab already has a SentGift component', () => {
+    it('sets the given gift box label', () => {
+      const prefab = new Prefab('Gift_Mail_Box', {
+        components: {
+          SentGift: new SentGiftComponent({
+            version: 1,
+            senderName: 'lolwut'
+          })
+        }
+      });
+
+      prefab.setGiftBoxLabel('topkek');
+      const giftBoxLabel = prefab.getGiftBoxLabel();
+
+      expect(giftBoxLabel).toStrictEqual('topkek');
+    });
+  });
+});
+
+describe('Prefab.setIntegrity()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Short_Sword_Blade');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.setIntegrity();
+      const expectedError = new Error('You must pass a number to set as the integrity.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the prefab cannot have a DurabilityModule component', () => {
+    it('sets no integrity', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.DurabilityModule;
+
+      prefab.setIntegrity(0.69);
+      const integrity = prefab.getIntegrity();
+
+      expect(integrity).toStrictEqual(1);
+    });
+  });
+
+  describe('when the prefab can have a DurabilityModule component', () => {
+    it('sets the given integrity', () => {
+      const prefab = new Prefab('Short_Sword_Blade');
+
+      prefab.setIntegrity(0.69);
+      const integrity = prefab.getIntegrity();
+
+      expect(integrity).toBeCloseTo(0.69, 2);
+    });
+  });
+
+  describe('when the prefab already has a DurabilityModule component', () => {
+    it('sets the given integrity', () => {
+      const prefab = new Prefab('Short_Sword_Blade', {
+        components: {
+          DurabilityModule: new DurabilityModuleComponent({
+            version: 1,
+            integrity: 0.1337
+          })
+        }
+      });
+
+      prefab.setIntegrity(0.69);
+      const integrity = prefab.getIntegrity();
+
+      expect(integrity).toBeCloseTo(0.69, 2);
+    });
+  });
+});
+
+describe('Prefab.setKinematic()', () => {
+  describe('when the prefab cannot have a NetworkRigidbody component', () => {
+    it('sets no isKinematic', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.NetworkRigidbody;
+
+      prefab.setKinematic(true);
+      const isKinematic = prefab.getKinematic();
+
+      expect(isKinematic).toStrictEqual(false);
+    });
+  });
+
+  describe('when the prefab can have a NetworkRigidbody component', () => {
+    it('sets the given isKinematic', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            isKinematic: false
+          })
+        }
+      });
+
+      prefab.setKinematic(true);
+      const isKinematic = prefab.getKinematic();
+
+      expect(isKinematic).toStrictEqual(true);
+    });
+  });
+
+  describe('when the prefab already has a NetworkRigidbody component', () => {
+    it('sets the given isKinematic', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setKinematic(true);
+      const isKinematic = prefab.getKinematic();
+
+      expect(isKinematic).toStrictEqual(true);
+    });
+  });
+
+  describe('when given no arguments', () => {
+    it('sets isKinematic of true', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setKinematic();
+      const isKinematic = prefab.getKinematic();
+
+      expect(isKinematic).toStrictEqual(true);
+    });
+  });
+});
+
+describe('Prefab.setMaterial()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Short_Sword_Blade');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.setMaterial();
+      const expectedError = new Error('You must pass a PhysicalMaterialPartHash to set as the material.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the prefab cannot have a PhysicalMaterialPart component', () => {
+    it('sets no material', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.PhysicalMaterialPart;
+
+      prefab.setMaterial(PhysicalMaterialPartHash.EvinonSteelAlloy);
+      const materialHash = prefab.getMaterial();
+
+      expect(materialHash).toStrictEqual(0);
+    });
+  });
+
+  describe('when the prefab can have a PhysicalMaterialPart component', () => {
+    describe('when given a material hash', () => {
+      it('sets the given material', () => {
+        const prefab = new Prefab('Short_Sword_Blade');
+
+        prefab.setMaterial(PhysicalMaterialPartHash.EvinonSteelAlloy);
+        const materialHash = prefab.getMaterial();
+
+        expect(materialHash).toStrictEqual(31502);
+      });
+    });
+
+    describe('when given a material name', () => {
+      it('sets the given material', () => {
+        const prefab = new Prefab('Short_Sword_Blade');
+
+        prefab.setMaterial('EvinonSteelAlloy');
+        const materialHash = prefab.getMaterial();
+
+        expect(materialHash).toStrictEqual(31502);
+      });
+    });
+  });
+
+  describe('when the prefab already has a PhysicalMaterialPart component', () => {
+    it('sets the given material', () => {
+      const prefab = new Prefab('Short_Sword_Blade', {
+        components: {
+          PhysicalMaterialPart: new PhysicalMaterialPartComponent({
+            version: 1,
+            materialHash: PhysicalMaterialPartHash.Gold
+          })
+        }
+      });
+
+      prefab.setMaterial(PhysicalMaterialPartHash.EvinonSteelAlloy);
+      const materialHash = prefab.getMaterial();
+
+      expect(materialHash).toStrictEqual(31502);
+    });
+  });
+});
+
+describe('Prefab.setOnFire()', () => {
+  describe('when the prefab cannot have a Fire entity', () => {
+    it('sets no isLit', () => {
+      const prefab = new Prefab('Anvil');
+      prefab.entities = {};
+
+      prefab.setOnFire(true);
+      const isLit = prefab.getOnFire();
+
+      expect(isLit).toStrictEqual(false);
+    });
+  });
+
+  describe('when the prefab can have a Fire entity', () => {
+    it('sets the given isLit', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setOnFire(true);
+      const isLit = prefab.getOnFire();
+
+      expect(isLit).toStrictEqual(true);
+    });
+  });
+
+  describe('when the prefab already has a Fire entity but no HeatSourceBase component', () => {
+    it('sets the given isLit', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        entities: {
+          Fire_30100: new Entity('Fire_30100')
+        }
+      });
+
+      prefab.setOnFire(true);
+      const isLit = prefab.getOnFire();
+
+      expect(isLit).toStrictEqual(true);
+    });
+  });
+
+  describe('when the prefab already has a Fire entity with a HeatSourceBase component', () => {
+    it('sets the given isLit', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        entities: {
+          Fire_30100: new Entity('Fire_30100', {
+            components: {
+              HeatSourceBase: new HeatSourceBaseComponent({
+                version: 1,
+                isLit: false
+              })
+            }
+          })
+        }
+      });
+
+      prefab.setOnFire(true);
+      const isLit = prefab.getOnFire();
+
+      expect(isLit).toStrictEqual(true);
+    });
+  });
+
+  describe('when given no arguments', () => {
+    it('sets isLit of true', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setOnFire();
+      const isLit = prefab.getOnFire();
+
+      expect(isLit).toStrictEqual(true);
+    });
+  });
+});
+
+describe('Prefab.setPosition()', () => {
+  describe('when the prefab cannot have a NetworkRigidbody component', () => {
+    it('sets the given position on prefab only', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.NetworkRigidbody;
+
+      prefab.setPosition({ x: 69, y: 420, z: 1337 });
+      const position = prefab.getPosition();
+
+      expect(position).toStrictEqual({ x: 69, y: 420, z: 1337 });
+      // @ts-expect-error Deleted object becomes `never`
+      expect(prefab.components.NetworkRigidbody?.position).toStrictEqual(undefined);
+    });
+  });
+
+  describe('when the prefab can have a NetworkRigidbody component', () => {
+    it('sets the given position on prefab and NetworkRigidbody component', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setPosition({ x: 69, y: 420, z: 1337 });
+      const position = prefab.getPosition();
+
+      expect(position).toStrictEqual({ x: 69, y: 420, z: 1337 });
+      expect(prefab.components.NetworkRigidbody?.position).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+
+  describe('when the prefab already has a NetworkRigidbody component', () => {
+    it('sets the given position on prefab and NetworkRigidbody component', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            position: { x: 88, y: -88, z: -88 }
+          })
+        }
+      });
+
+      prefab.setPosition({ x: 69, y: 420, z: 1337 });
+      const position = prefab.getPosition();
+
+      expect(position).toStrictEqual({ x: 69, y: 420, z: 1337 });
+      expect(prefab.components.NetworkRigidbody?.position).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+});
+
+describe('Prefab.setRotation()', () => {
+  describe('when the prefab cannot have a NetworkRigidbody component', () => {
+    it('sets the given rotation on prefab only', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.NetworkRigidbody;
+
+      prefab.setRotation({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+      const rotation = prefab.getRotation();
+
+      expect(rotation).toStrictEqual({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+      // @ts-expect-error Deleted object becomes `never`
+      expect(prefab.components.NetworkRigidbody?.rotation).toStrictEqual(undefined);
+    });
+  });
+
+  describe('when the prefab can have a NetworkRigidbody component', () => {
+    it('sets the given rotation on prefab and NetworkRigidbody component', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setRotation({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+      const rotation = prefab.getRotation();
+
+      expect(rotation).toStrictEqual({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+      expect(prefab.components.NetworkRigidbody?.rotation).toStrictEqual({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+    });
+  });
+
+  describe('when the prefab already has a NetworkRigidbody component', () => {
+    it('sets the given rotation on prefab and NetworkRigidbody component', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            rotation: { x: 0.88, y: -0.88, z: -0.88, w: 0.88 }
+          })
+        }
+      });
+
+      prefab.setRotation({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+      const rotation = prefab.getRotation();
+
+      expect(rotation).toStrictEqual({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+      expect(prefab.components.NetworkRigidbody?.rotation).toStrictEqual({ x: 0.69, y: 0.42, z: -0.1337, w: 0.88 });
+    });
+  });
+});
+
+describe('Prefab.setScale()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Short_Sword_Blade');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.setScale();
+      const expectedError = new Error('You must pass a number to set as the scale.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  it('sets the given scale', () => {
+    const prefab = new Prefab('Short_Sword_Blade');
+
+    prefab.setScale(0.69);
+    const scale = prefab.getScale();
+
+    expect(scale).toBeCloseTo(0.69, 2);
+  });
+});
+
+describe('Prefab.setServerSleeping()', () => {
+  describe('when the prefab cannot have a NetworkRigidbody component', () => {
+    it('sets no isServerSleeping', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.NetworkRigidbody;
+
+      prefab.setServerSleeping(true);
+      const isServerSleeping = prefab.getServerSleeping();
+
+      expect(isServerSleeping).toStrictEqual(false);
+    });
+  });
+
+  describe('when the prefab can have a NetworkRigidbody component', () => {
+    it('sets the given isServerSleeping', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setServerSleeping(true);
+      const isServerSleeping = prefab.getServerSleeping();
+
+      expect(isServerSleeping).toStrictEqual(true);
+    });
+  });
+
+  describe('when the prefab already has a NetworkRigidbody component', () => {
+    it('sets the given isServerSleeping', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            isServerSleeping: false
+          })
+        }
+      });
+
+      prefab.setServerSleeping(true);
+      const isServerSleeping = prefab.getServerSleeping();
+
+      expect(isServerSleeping).toStrictEqual(true);
+    });
+  });
+
+  describe('when given no arguments', () => {
+    it('sets isServerSleeping of true', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setServerSleeping();
+      const isServerSleeping = prefab.getServerSleeping();
+
+      expect(isServerSleeping).toStrictEqual(true);
+    });
+  });
+});
+
+describe('Prefab.setServings()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Potion_Medium');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.setServings();
+      const expectedError = new Error('You must pass a number to set as the amount of servings.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the prefab cannot have a LiquidContainer component', () => {
+    it('sets no servings', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.LiquidContainer;
+
+      prefab.setServings(69);
+      const servings = prefab.getServings();
+
+      expect(servings).toStrictEqual(0);
+    });
+  });
+
+  describe('when the prefab can have a LiquidContainer component', () => {
+    it('sets the given amount of servings', () => {
+      const prefab = new Prefab('Potion_Medium');
+
+      prefab.setServings(69);
+      const servings = prefab.getServings();
+
+      expect(servings).toStrictEqual(69);
+    });
+  });
+
+  describe('when the prefab already has a LiquidContainer component', () => {
+    it('sets the given amount of servings', () => {
+      const prefab = new Prefab('Potion_Medium', {
+        components: {
+          LiquidContainer: new LiquidContainerComponent({
+            version: 1,
+            contentLevel: 1337
+          })
+        }
+      });
+
+      prefab.setServings(69);
+      const servings = prefab.getServings();
+
+      expect(servings).toStrictEqual(69);
+    });
+  });
+});
+
+describe('Prefab.setSpawnArea()', () => {
+  describe('when given invalid arguments', () => {
+    it('throws an error', () => {
+      const prefab = new Prefab('Directional_Encounter');
+
+      // @ts-expect-error Passing invalid arguments
+      const expectedToThrow = () => prefab.setSpawnArea();
+      const expectedError = new Error('You must pass a population definition hash or name to set on this spawn area.');
+
+      expect(expectedToThrow).toThrowError(expectedError);
+    });
+  });
+
+  describe('when the prefab cannot have PopulationSpawnArea and SpawnArea components', () => {
+    it('sets no spawn area', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.PopulationSpawnArea;
+      delete prefab.components.SpawnArea;
+
+      prefab.setSpawnArea(PopulationDefinitionHash.WyrmPopulation);
+
+      expect(prefab.components.PopulationSpawnArea).toStrictEqual(undefined);
+      expect(prefab.components.SpawnArea).toStrictEqual(undefined);
+    });
+  });
+
+  describe('when the prefab can have PopulationSpawnArea and SpawnArea components', () => {
+    describe('when given the required arguments', () => {
+      describe('when given a population definition hash', () => {
+        it('sets the given population on the spawn area with additional default values', () => {
+          const prefab = new Prefab('Directional_Encounter');
+
+          prefab.setSpawnArea(PopulationDefinitionHash.WyrmPopulation);
+
+          expect(prefab.components.PopulationSpawnArea?.currentPopulation).toStrictEqual(5);
+          expect(prefab.components.PopulationSpawnArea?.isOneOff).toStrictEqual(false);
+          expect(prefab.components.PopulationSpawnArea?.isPopulationStarted).toStrictEqual(true);
+          expect(prefab.components.PopulationSpawnArea?.maxPopulation).toStrictEqual(20);
+          expect(prefab.components.PopulationSpawnArea?.numberOfSpawnPoints).toStrictEqual(40);
+          expect(prefab.components.PopulationSpawnArea?.startingPopulation).toStrictEqual(5);
+          expect(prefab.components.SpawnArea?.size).toStrictEqual(5);
+        });
+      });
+
+      describe('when given a population definition name', () => {
+        it('sets the given population on the spawn area with additional default values', () => {
+          const prefab = new Prefab('Directional_Encounter');
+
+          prefab.setSpawnArea('WyrmPopulation');
+
+          expect(prefab.components.PopulationSpawnArea?.currentPopulation).toStrictEqual(5);
+          expect(prefab.components.PopulationSpawnArea?.isOneOff).toStrictEqual(false);
+          expect(prefab.components.PopulationSpawnArea?.isPopulationStarted).toStrictEqual(true);
+          expect(prefab.components.PopulationSpawnArea?.maxPopulation).toStrictEqual(20);
+          expect(prefab.components.PopulationSpawnArea?.numberOfSpawnPoints).toStrictEqual(40);
+          expect(prefab.components.PopulationSpawnArea?.startingPopulation).toStrictEqual(5);
+          expect(prefab.components.SpawnArea?.size).toStrictEqual(5);
+        });
+      });
+    });
+
+    describe('when given the additional arguments', () => {
+      it('sets the given population on the spawn area with additional given values', () => {
+        const prefab = new Prefab('Directional_Encounter');
+
+        prefab.setSpawnArea(PopulationDefinitionHash.WyrmPopulation, {
+          currentPopulation: 69,
+          isOneOff: true,
+          isPopulationStarted: false,
+          maxPopulation: 1337,
+          numberOfSpawnPoints: 69,
+          size: 420,
+          startingPopulation: 1337
+        });
+
+        expect(prefab.components.PopulationSpawnArea?.currentPopulation).toStrictEqual(69);
+        expect(prefab.components.PopulationSpawnArea?.isOneOff).toStrictEqual(true);
+        expect(prefab.components.PopulationSpawnArea?.isPopulationStarted).toStrictEqual(false);
+        expect(prefab.components.PopulationSpawnArea?.maxPopulation).toStrictEqual(1337);
+        expect(prefab.components.PopulationSpawnArea?.numberOfSpawnPoints).toStrictEqual(69);
+        expect(prefab.components.PopulationSpawnArea?.startingPopulation).toStrictEqual(1337);
+        expect(prefab.components.SpawnArea?.size).toStrictEqual(420);
+      });
+    });
+  });
+
+  describe('when the prefab already has PopulationSpawnArea and SpawnArea components', () => {
+    it('sets the given spawn area', () => {
+      const prefab = new Prefab('Directional_Encounter', {
+        components: {
+          PopulationSpawnArea: new PopulationSpawnAreaComponent({
+            version: 2,
+            definition: PopulationDefinitionHash.TurabadaOverworldPopulation
+          }),
+          SpawnArea: new SpawnAreaComponent({
+            version: 1,
+            size: 1337
+          })
+        }
+      });
+
+      prefab.setSpawnArea(PopulationDefinitionHash.WyrmPopulation, { size: 69 });
+
+      expect(prefab.components.PopulationSpawnArea?.definition).toStrictEqual(PopulationDefinitionHash.WyrmPopulation);
+      expect(prefab.components.SpawnArea?.size).toStrictEqual(69);
+    });
+  });
+});
+
+describe('Prefab.setVelocity()', () => {
+  describe('when the prefab cannot have a NetworkRigidbody component', () => {
+    it('sets no velocity', () => {
+      const prefab = new Prefab('Anvil');
+      delete prefab.components.NetworkRigidbody;
+
+      prefab.setVelocity({ x: 69, y: 420, z: 1337 });
+      const velocity = prefab.getVelocity();
+
+      expect(velocity).toStrictEqual({ x: 0, y: 0, z: 0 });
+    });
+  });
+
+  describe('when the prefab can have a NetworkRigidbody component', () => {
+    it('sets the given velocity', () => {
+      const prefab = new Prefab('Grass_Clump');
+
+      prefab.setVelocity({ x: 69, y: 420, z: 1337 });
+      const velocity = prefab.getVelocity();
+
+      expect(velocity).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+
+  describe('when the prefab already has a NetworkRigidbody component', () => {
+    it('sets the given velocity', () => {
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({
+            version: 1,
+            velocity: { x: 88, y: -88, z: -88 }
+          })
+        }
+      });
+
+      prefab.setVelocity({ x: 69, y: 420, z: 1337 });
+      const velocity = prefab.getVelocity();
+
+      expect(velocity).toStrictEqual({ x: 69, y: 420, z: 1337 });
+    });
+  });
+});
+
+describe('Prefab.toBinary()', () => {
+  it('returns the BinaryString of the prefab', () => {
+    const prefab = new Prefab('Torch', {
+      components: {
+        Pickup: new PickupComponent({ version: 2 })
+      },
+      entities: {
+        Fire_30100: new Entity('Fire_30100', {
+          components: {
+            HeatSourceBase: new HeatSourceBaseComponent({
+              version: 1,
+              isLit: true
+            })
+          }
+        })
+      },
+      children: [{ parentHash: 0, prefab: new Prefab('Guard') }]
+    });
+
+    const componentVersions = prefab.getComponentVersions();
+    const binaryString = prefab.toBinary(componentVersions);
+
+    expect(binaryString).toStrictEqual(
+      '000000000000000011011101011110100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000111111100000000000000000000000010101101011000100000011101101100000000000000000000000000100000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111010110010100000000000000000000000000110000101111101001110111111011110100000000000000000000000000000000110000110000000000000000000000000000000001010001111101101100000000000000000000000111000000011101011110000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000011001001110110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
+    );
+  });
+});
+
+describe('Prefab.toSaveString()', () => {
+  it('returns the SaveString of the prefab', () => {
+    const prefab = new Prefab('Torch', {
+      components: {
+        NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+        Pickup: new PickupComponent({ version: 2 })
+      },
+      entities: {
+        Fire_30100: new Entity('Fire_30100', {
+          components: {
+            HeatSourceBase: new HeatSourceBaseComponent({
+              version: 1,
+              isLit: true
+            })
+          }
+        })
+      },
+      children: [{ parentHash: 0, prefab: new Prefab('Guard') }]
+    });
+
+    const saveString = prefab.toSaveString();
+
+    expect(saveString).toStrictEqual(
+      '56698,204,56698,0,0,0,0,0,0,1065353216,1065353216,2290978823,418,0,0,0,0,0,0,1065353216,0,0,0,0,0,0,363610349,2147483664,536870912,0,0,7525,48,3198024656,12,805306368,85945344,459223,2147483648,0,134217728,1614,3221225472,0,0,0,0,0,33292288,33292288,0,0,0,|3,2290978823,1,1454441398,2,4109360768,1,'
+    );
+  });
+
+  describe('when the binary data does not align to full bytes', () => {
+    it('returns a SaveString containing padded bits of the prefab', () => {
+      const prefab = new Prefab('Torch', {
+        components: {
+          NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+          Pickup: new PickupComponent({ version: 2 })
+        },
+        entities: {
+          Fire_30100: new Entity('Fire_30100', {
+            components: {
+              HeatSourceBase: new HeatSourceBaseComponent({
+                version: 1,
+                isLit: true
+              })
+            }
+          })
+        },
+        children: [{ parentHash: 0, prefab: new Prefab('Guard') }]
+      });
+
+      const spy = vi.spyOn(prefab, 'toBinary');
+      spy.mockImplementationOnce(
+        /* Added 25 false bits at the end to force Prefab.toSaveString() to skip bit alignment. */
+        () =>
+          '000000000000000011011101011110100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000111111100000000000000000000000100010001000110110010000000001110000000000000000000000011010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101011010110001000000111011011000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110101100101000000000000000000000000001100001011111010011101111110111101000000000000000000000000000000001100001100000000000000000000000000000000010100011111011011000000000000000000000001110000000111010111100000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000110010011101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' as BinaryString
+      );
+
+      const saveString = prefab.toSaveString();
+
+      expect(saveString).toStrictEqual(
+        '56698,204,56698,0,0,0,0,0,0,1065353216,1065353216,2290978823,418,0,0,0,0,0,0,1065353216,0,0,0,0,0,0,363610349,2147483664,536870912,0,0,7525,48,3198024656,12,805306368,85945344,459223,2147483648,0,134217728,1614,3221225472,0,0,0,0,0,33292288,33292288,0,0,0,|3,2290978823,1,1454441398,2,4109360768,1,'
+      );
+    });
+  });
+
+  describe('when the prefab contains components with indeterminate versions', () => {
+    describe('when not excluding component versions', () => {
+      it('throws an error', () => {
+        const prefab = new Prefab('Torch', {
+          components: {
+            Unknown: [
+              new UnsupportedComponent({
+                hash: 1337,
+                name: 'Unknown_1337',
+                rawData: '11110111001100010000' as BinaryString,
+                version: 0
+              })
+            ]
+          }
+        });
+
+        const expectedToThrow = () => prefab.toSaveString();
+        const expectedError = new Error(
+          'Prefab contains components with version `0`. Current in-game versions for those components are not available. The produced save string will not contain component versions and may not be spawnable in-game.\n\nYou may call `.toSaveString(true)` to force producing a save string with this limitation.\n'
+        );
+
+        expect(expectedToThrow).toThrowError(expectedError);
+      });
+    });
+
+    describe('when ignoring indeterminate component versions', () => {
+      it('returns a save string without component versions', () => {
+        const prefab = new Prefab('Torch', {
+          components: {
+            NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 }),
+            Unknown: [
+              new UnsupportedComponent({
+                hash: 1337,
+                name: 'Unknown_1337',
+                rawData: '11110111001100010000' as BinaryString,
+                version: 0
+              })
+            ]
+          }
+        });
+
+        const saveString = prefab.toSaveString({
+          ignoreIndeterminateComponentVersions: true
+        });
+
+        expect(saveString).toStrictEqual(
+          '56698,116,56698,0,0,0,0,0,0,1065353216,1065353216,2290978823,418,0,0,0,0,0,0,1065353216,0,0,0,0,0,0,334,1073741829,1036795904,0,0,'
+        );
+      });
+    });
+
+    describe('when excluding component versions', () => {
+      it('returns a save string without component versions', () => {
+        const prefab = new Prefab('Torch', {
+          components: {
+            NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 })
+          }
+        });
+
+        const saveString = prefab.toSaveString({
+          excludeComponentVersions: true
+        });
+
+        expect(saveString).toStrictEqual(
+          '56698,108,56698,0,0,0,0,0,0,1065353216,1065353216,2290978823,418,0,0,0,0,0,0,1065353216,0,0,0,0,0,0,0,0,0,'
+        );
+      });
+    });
+  });
+});
diff --git a/src/Prefab.ts b/src/Prefab.ts
new file mode 100644
index 0000000..86565df
--- /dev/null
+++ b/src/Prefab.ts
@@ -0,0 +1,1869 @@
+import type { Component } from './components/Component.js';
+import type { ATTPrefabHash } from './types/ATTPrefabHash.js';
+import type { ATTPrefabName } from './types/ATTPrefabName.js';
+import type { AngularVelocity } from './types/AngularVelocity.js';
+import type { BinaryString } from './types/BinaryString.js';
+import type { EntityKey } from './types/EntityKey.js';
+import type { PopulationDefinitionName } from './types/PopulationDefinitionName.js';
+import type { Position } from './types/Position.js';
+import type { PrefabChild } from './types/PrefabChild.js';
+import type { PrefabComponents } from './types/PrefabComponents.js';
+import type { PrefabEntities } from './types/PrefabEntities.js';
+import type { Rotation } from './types/Rotation.js';
+import type { SaveString } from './types/SaveString.js';
+import type { SetSpawnAreaProps } from './types/SetSpawnAreaProps.js';
+import type { Velocity } from './types/Velocity.js';
+
+import { inspect } from 'node:util';
+
+import { BinaryData, type BinaryDataOptions } from './BinaryData.js';
+import { BinaryReader } from './BinaryReader.js';
+import { BinaryWriter } from './BinaryWriter.js';
+import { Entity } from './Entity.js';
+import { DurabilityModuleComponent } from './components/DurabilityModuleComponent.js';
+import { HeatSourceBaseComponent } from './components/HeatSourceBaseComponent.js';
+import { LiquidContainerComponent } from './components/LiquidContainerComponent.js';
+import { NetworkRigidbodyComponent } from './components/NetworkRigidbodyComponent.js';
+import { PhysicalMaterialPartComponent } from './components/PhysicalMaterialPartComponent.js';
+import { PopulationSpawnAreaComponent } from './components/PopulationSpawnAreaComponent.js';
+import { SentGiftComponent } from './components/SentGiftComponent.js';
+import { SpawnAreaComponent } from './components/SpawnAreaComponent.js';
+import * as constants from './constants.js';
+import { ATTPrefabs } from './types/ATTPrefabs.js';
+import { ComponentHash } from './types/ComponentHash.js';
+import { PhysicalMaterialPartHash } from './types/PhysicalMaterialPartHash.js';
+import { PopulationDefinitionHash } from './types/PopulationDefinitionHash.js';
+import { isSavableComponent } from './utils/isSavableComponent.js';
+import { readChildren } from './utils/readChildren.js';
+import { readComponents } from './utils/readComponents.js';
+import { readEntities } from './utils/readEntities.js';
+import { writeChildren } from './utils/writeChildren.js';
+import { writeComponents } from './utils/writeComponents.js';
+import { writeEntities } from './utils/writeEntities.js';
+
+type PrefabHash<TPrefabName extends ATTPrefabName> = (typeof ATTPrefabs)[TPrefabName]['hash'];
+
+type PrefabName<TPrefabName extends ATTPrefabName> = (typeof ATTPrefabs)[TPrefabName]['name'];
+
+export type ToSaveStringOptions = {
+  excludeComponentVersions?: boolean | undefined;
+  ignoreIndeterminateComponentVersions?: boolean | undefined;
+};
+
+export type PrefabProps<TPrefabName extends ATTPrefabName> = {
+  position?: Position | undefined;
+  rotation?: Rotation | undefined;
+  scale?: number | undefined;
+  components?: Partial<PrefabComponents> | undefined;
+  entities?: Partial<PrefabEntities<TPrefabName>> | undefined;
+  children?: PrefabChild[] | undefined;
+};
+
+/* c8 ignore start */
+const FALLBACK_DURABILITY_MODULE_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.DurabilityModule) ??
+  constants.latestDurabilityModuleComponentVersion;
+
+const FALLBACK_HEAT_SOURCE_BASE_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.HeatSourceBase) ??
+  constants.latestHeatSourceBaseComponentVersion;
+
+const FALLBACK_LIQUID_CONTAINER_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.LiquidContainer) ??
+  constants.latestLiquidContainerComponentVersion;
+
+export const FALLBACK_PHYSICAL_MATERIAL_PART_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.PhysicalMaterialPart) ??
+  constants.latestPhysicalMaterialPartComponentVersion;
+
+const FALLBACK_POPULATION_SPAWN_AREA_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.PopulationSpawnArea) ??
+  constants.latestPopulationSpawnAreaComponentVersion;
+
+const FALLBACK_NETWORK_RIGIDBODY_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.NetworkRigidbody) ??
+  constants.latestNetworkRigidbodyComponentVersion;
+
+const FALLBACK_SENT_GIFT_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.SentGift) ?? constants.latestSentGiftComponentVersion;
+
+const FALLBACK_SPAWN_AREA_VERSION =
+  constants.latestSupportedComponentVersions.get(ComponentHash.SpawnArea) ?? constants.latestSpawnAreaComponentVersion;
+/* c8 ignore stop */
+
+/**
+ * A JavaScript object representation of an _A Township Tale_ in-game prefab.
+ *
+ * @see [Class: `Prefab`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/Prefab.md)
+ * @since v3.0.0
+ *
+ * @example
+ * import { Prefab } from 'att-string-transcoder';
+ *
+ * const prefab = new Prefab('Handle_Short');
+ * // or
+ * const prefab = Prefab.fromSaveString<'Handle_Short'>(mySaveString);
+ * // or
+ * const prefab = Prefab.fromBinary<'Handle_Short'>(myBinaryString);
+ */
+export class Prefab<TPrefabName extends ATTPrefabName = ATTPrefabName> {
+  /**
+   * The name of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * const name = prefab.name;
+   * // `name` is `'Handle_Short'`
+   */
+  readonly name: PrefabName<TPrefabName>;
+
+  /**
+   * The hash of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * const hash = prefab.hash;
+   * // `hash` is `42230`
+   */
+  readonly hash: PrefabHash<TPrefabName>;
+
+  /**
+   * The position of the prefab.
+   *
+   * ⚠️ Note that although you can safely read from this public property, you should not modify this
+   * property directly. This is because some prefabs also use a `NetworkRigidbodyComponent` to
+   * control their position. You can safely set the position of a prefab using the
+   * `setPosition(position)` method.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short', {
+   *   position: { x: 420, y: 69, z: 1337 }
+   * });
+   *
+   * const position = prefab.position;
+   * // `position` is `{ x: 420, y: 69, z: 1337 }`
+   */
+  position: Position;
+
+  /**
+   * The rotation of the prefab.
+   *
+   * Note that although you can safely read from this public property, you should not modify this
+   * property directly. This is because some prefabs also use a `NetworkRigidbodyComponent` to
+   * control their rotation. You can safely set the rotation of a prefab using the
+   * `setRotation(rotation)` method.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short', {
+   *   rotation: { x: 0.42, y: -0.69, z: -0.1337, w: 0.88 }
+   * });
+   *
+   * const rotation = prefab.rotation;
+   * // `rotation` is `{ x: 0.42, y: -0.69, z: -0.1337, w: 0.88 }`
+   */
+  rotation: Rotation;
+
+  /**
+   * The scale of the prefab.
+   *
+   * Contains the scale of the prefab. You can also set the scale of a prefab using the
+   * `setScale(scale)` method.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short', {
+   *   scale: 0.69
+   * });
+   *
+   * const scale = prefab.scale;
+   * // `scale` is approx. `0.69` (within JavaScript floating point precision)
+   */
+  scale: number;
+
+  /**
+   * A map of the stored components.
+   *
+   * Provides access to the components stored in this prefab. Components are keyed to their
+   * respective names, unless its data contained an unrecognised hash. In that case, the component
+   * will be stored in an array under the `Unknown` key.
+   *
+   * 💡 It might be easier to add components using the `addComponent(component)` method.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short', {
+   *   components: {
+   *     NetworkRigidbody: new NetworkRigidbodyComponent({ version: 1 })
+   *   }
+   * });
+   *
+   * const components = prefab.components;
+   * // `components` is `{
+   * //   NetworkRigidbody: NetworkRigidbodyComponent {
+   * //     hash: 2290978823,
+   * //     name: 'NetworkRigidbody',
+   * //     position: { x: 0, y: 0, z: 0 },
+   * //     rotation: { x: 0, y: 0, z: 0, w: 1 },
+   * //     isKinematic: false,
+   * //     isServerSleeping: false,
+   * //     velocity: { x: 0, y: 0, z: 0 },
+   * //     angularVelocity: { x: 0, y: 0, z: 0 }
+   * //   },
+   * //   Unknown: []
+   * // }`
+   */
+  components: PrefabComponents;
+
+  /**
+   * A map of the stored entities.
+   *
+   * Provides access to the entities stored in this prefab. Entities are keyed to a combination of
+   * their respective names and hashes, unless its data contained an unrecognised hash. In that
+   * case, the entity will be keyed as `Unknown_` followed by its hash. The reason that entities
+   * cannot be keyed without their hashes (like components) is because some prefabs have multiple
+   * entities with the same name. For example, the `Handle_Fist` prefab has several `Slot_Deco`
+   * entities that are only differentiated by their hash. Conversely, it's also possible that an
+   * entity exists on different prefabs with the same name but different hashes. For example, the
+   * `Fire` entity exists on the `Infinite_Fire` prefab with hash `8488`, but exists on the
+   * `Grass_Clump` prefab with hash `30100`. For this reason, _ATT String Transcoder_ uses spawn
+   * infodumps from the game to figure out which entities belong to which prefabs and uses this data
+   * to provide you with auto-complete options.
+   *
+   * ⚠️ Unfortunately this means that it's not easy to tell upfront which hash a `Fire` entity has on
+   * a prefab that you're building. Please ensure that you assign a key that is identical to the
+   * entity key (which is name, underscore, and hash).
+   *
+   * 💡 It might be easier to add entities using the `addEntity(entity)` method.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short', {
+   *   entities: {
+   *     // Please note the keys include the hash, not just the name.
+   *     Slot_Multi_6136: new Entity('Slot_Multi_6136'),
+   *     Slot_Multi_6138: new Entity('Slot_Multi_6138'),
+   *     Unknown_1337: new Entity('Unknown', { hash: 1337 })
+   *   }
+   * });
+   *
+   * const entities = prefab.entities;
+   * // `entities` is `{
+   * //   Slot_Multi_6136: Entity {
+   * //     hash: 6136,
+   * //     name: 'Slot_Multi',
+   * //     isAlive: true,
+   * //     components: { Unknown: [] }
+   * //   },
+   * //   Slot_Multi_6138: Entity {
+   * //     hash: 6138,
+   * //     name: 'Slot_Multi',
+   * //     isAlive: true,
+   * //     components: { Unknown: [] }
+   * //   },
+   * //   Unknown_1337: Entity {
+   * //     hash: 1337,
+   * //     name: 'Unknown',
+   * //     isAlive: true,
+   * //     components: { Unknown: [] }
+   * //   },
+   * // }`
+   */
+  entities: PrefabEntities<TPrefabName>;
+
+  /**
+   * An array of the stored child prefabs.
+   *
+   * Contains an array of objects that map nested prefabs to entities on the current prefab.
+   *
+   * ⚠️ Note that the entity _does not need to exist_ in the prefab in your program! The ATT game
+   * server will fill in the blanks. For example, if you create a save string for a `Handle_Short`
+   * prefab with several children and no entities on it, and spawn it in-game, it will in fact
+   * have all its usual entities to which child prefabs can attach.
+   *
+   * 💡 It might be easier to add child prefabs using the `addChildPrefab(parentKey, childPrefab)`
+   * method.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short', {
+   *   children: [
+   *     {
+   *       // Please note the entity hash below wasn't defined elsewhere in this prefab, yet this will work when spawned in-game.
+   *       parentHash: 6136, // The hash for `Slot_Multi_6136` on `Handle_Short` prefab.
+   *       prefab: new Prefab('Guard')
+   *     }
+   *   ]
+   * });
+   *
+   * const children = prefab.children;
+   * // `children` is `[
+   * //   {
+   * //     parentHash: 6136,
+   * //     prefab: Prefab {
+   * //       name: 'Guard',
+   * //       hash: 51672,
+   * //       position: { x: 0, y: 0, z: 0 },
+   * //       rotation: { x: 0, y: 0, z: 0, w: 1 }
+   * //       scale: 1,
+   * //       components: { Unknown: [] },
+   * //       entities: {},
+   * //       children: []
+   * //     }
+   * //   }
+   * // ]`
+   */
+  children: PrefabChild[];
+
+  /**
+   * Creates a new `Prefab` from a list of known _A Township Tale_ prefab names. You may optionally
+   * provide additional properties in the second argument.
+   *
+   * @see [Class: `Prefab`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/Prefab.md)
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const simple = new Prefab('Grass_Clump');
+   *
+   * const advanced = new Prefab('Wooden_Stake', {
+   *   position: { x: 133.7, y: 420, z: 69 },
+   *   rotation: { x: 0.3, y: 0.4, z: 0.1, w: 0.8 },
+   *   scale: 1.5,
+   *   components: {
+   *     NetworkRigidbody: new NetworkRigidbodyComponent({
+   *       version: 1,
+   *       position: { x: 133.7, y: 420, z: 69 },
+   *       rotation: { x: 0.3, y: 0.4, z: 0.1, w: 0.8 },
+   *       isKinematic: false,
+   *       isServerSleeping: false,
+   *       velocity: { x: 0, y: 1, z: 0 },
+   *       angularVelocity: { x: 0, y: 1, z: 0 }
+   *     })
+   *   },
+   *   entities: {
+   *     Slot_Multi_11474: new Entity('Slot_Multi_11474')
+   *   },
+   *   children: [
+   *     {
+   *       parentHash: 11474,
+   *       prefab: new Prefab('Grass_Clump', {
+   *         entities: {
+   *           Fire_30100: new Entity('Fire_30100', {
+   *             components: {
+   *               HeatSourceBase: new HeatSourceBaseComponent({
+   *                 version: 2,
+   *                 isLit: true,
+   *                 progress: 0.8
+   *               })
+   *             }
+   *           })
+   *         }
+   *       })
+   *     }
+   *   ]
+   * });
+   */
+  constructor(
+    prefabName: TPrefabName,
+    { position, rotation, scale, components, entities, children }: PrefabProps<TPrefabName> = {}
+  ) {
+    this.hash = ATTPrefabs[prefabName].hash;
+    this.name = prefabName;
+    this.position = position ?? { x: 0, y: 0, z: 0 };
+    this.rotation = rotation ?? { x: 0, y: 0, z: 0, w: 1 };
+    this.scale = scale ?? 1;
+    this.components = { ...components, Unknown: components?.Unknown ?? [] } as PrefabComponents;
+    this.entities = { ...entities } as PrefabEntities<TPrefabName>;
+    this.children = children ?? [];
+  }
+
+  /**
+   * Attaches a `Prefab` to this prefab as a child. It can optionally be attached onto one of this
+   * prefab's embedded entities, which is required for most child prefabs under normal circumstances.
+   * If you do not specify a `parentKey`, you may pass `null` to create a "floating" child. It will
+   * be part of this prefab's hierarchy but will most likely behave unexpectedly in the game.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const parent = new Prefab('Handle_Short');
+   * const child = new Prefab('Guard');
+   *
+   * parent.addChildPrefab('Slot_Large_SwordType_Craft_54356', child);
+   */
+  addChildPrefab(parentKey: Exclude<EntityKey<TPrefabName>, 'Unknown'> | null, childPrefab: Prefab): this {
+    if (typeof parentKey === 'undefined' || typeof childPrefab === 'undefined') {
+      throw new Error(
+        'You must pass a parent prefab entity hash (or null) and a child prefab to add as a child to this prefab.'
+      );
+    }
+
+    let entityHash: number;
+
+    if (parentKey === null) {
+      entityHash = 0;
+    } else {
+      const entities = ATTPrefabs[this.name].embedded as Readonly<
+        Record<string, { hash: number; name: string; savables: Record<string, { hash: number; name: string }> }>
+      >;
+
+      const entity = entities[parentKey as string];
+
+      if (typeof entity === 'undefined') {
+        throw new Error(`"${String(parentKey)}" is not a valid entity on "${this.name}".`);
+      }
+
+      entityHash = entity.hash;
+    }
+
+    this.children = [
+      ...this.children,
+      {
+        parentHash: entityHash,
+        prefab: childPrefab
+      }
+    ];
+
+    return this;
+  }
+
+  /**
+   * Adds a `Component` to the prefab. Will override any existing component with that name.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { NetworkRigidbodyComponent, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   * const component = new NetworkRigidbodyComponent({ version: 1 });
+   *
+   * prefab.addComponent(component);
+   */
+  addComponent(component: Component): this {
+    this.components = {
+      ...this.components,
+      [component.name]: component
+    };
+
+    return this;
+  }
+
+  /**
+   * Adds an `Entity` to the prefab. Will override any existing entity with that key.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Entity, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   * const entity = new Entity<'Handle_Short'>('Slot_Multi_6136');
+   *
+   * prefab.addEntity(entity);
+   */
+  addEntity(entity: Entity<TPrefabName>): this {
+    this.entities = {
+      ...this.entities,
+      [`${entity.name}_${entity.hash}`]: entity
+    };
+
+    return this;
+  }
+
+  /**
+   * Adds a `Prefab` gift to this prefab's `SentGift` component. You may call this method more than
+   * once to add additional gifts.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const box = new Prefab('Gift_Mail_Box');
+   * const gift = new Prefab('Dynamite');
+   *
+   * box.addGift(gift);
+   */
+  addGift(giftPrefab: Prefab): this {
+    if (typeof giftPrefab === 'undefined') {
+      throw new Error('You must pass a gift prefab to add to this prefab as a gift.');
+    }
+
+    if (isSavableComponent('SentGift', this.name)) {
+      const version = this.components.SentGift?.version ?? FALLBACK_SENT_GIFT_VERSION;
+      const saveString = giftPrefab.toSaveString();
+      const [dataString, versionsString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined' || dataString.length === 0) {
+        throw new Error(`Gift prefab data is corrupted.`);
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+      const hash = unsignedIntegers.shift();
+      const bytes = unsignedIntegers.shift();
+      const chunkVersioning = versionsString?.split(',').map(Number) ?? [];
+
+      if (typeof hash === 'undefined' || typeof bytes === 'undefined' || bytes === 0) {
+        throw new Error(`Gift prefab data is corrupted.`);
+      }
+
+      this.components.SentGift = new SentGiftComponent({
+        ...this.components.SentGift,
+        version,
+        gifts: [
+          ...(this.components.SentGift?.gifts ?? []),
+          {
+            data: unsignedIntegers,
+            messageSizeInBytes: bytes,
+            hash,
+            chunkVersioning
+          }
+        ]
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Returns a deep clone of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const original = new Prefab('Guard').setMaterial('Mythril');
+   * const clone = original.clone();
+   *
+   * clone.setMaterial('Gold');
+   *
+   * const originalMaterial = original.getMaterial();
+   * // `originalMaterial` is still `31174` (Mythril)
+   *
+   * const cloneMaterial = clone.getMaterial();
+   * // `cloneMaterial` is `56394` (Gold)
+   */
+  clone(options: ToSaveStringOptions = {}): Prefab<TPrefabName> {
+    return Prefab.fromSaveString<TPrefabName>(this.toSaveString(options));
+  }
+
+  /**
+   * Creates a `Prefab` from reading the prefab's binary data stored in a `SaveString`.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { BinaryReader, ComponentHash, Prefab, type BinaryString } from 'att-string-transcoder';
+   *
+   * const binaryString = `0000000000000000101001001111011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000001111111000000000000000000000000101011010110001000000111011011000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000`;
+   *
+   * const reader = new BinaryReader(binaryString as BinaryString);
+   *
+   * const componentVersions = new Map<number, number>([
+   *   [ComponentHash.NetworkRigidbody, 1],
+   *   [ComponentHash.PhysicalMaterialPart, 1],
+   *   [ComponentHash.Pickup, 1]
+   *   // etc...
+   * ]);
+   *
+   * const prefab = Prefab.fromBinary<'Handle_Short'>(reader, componentVersions);
+   */
+  static fromBinary<TPrefabName extends ATTPrefabName = ATTPrefabName>(
+    reader: BinaryReader,
+    componentVersions?: Map<number, number>
+  ): Prefab<TPrefabName> {
+    const versions = componentVersions ?? constants.latestSupportedComponentVersions;
+
+    /**
+     * @property {number} hash
+     */
+    const hash = reader.readUnsignedInteger();
+
+    const name = constants.attPrefabNames[hash as ATTPrefabHash];
+
+    if (typeof name === 'undefined') throw new Error(`Cannot find ATT Prefab with hash ${hash}.`);
+
+    return new Prefab<TPrefabName>(name as TPrefabName, {
+      /**
+       * @property {Position} position
+       */
+      position: {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat()
+      },
+
+      /**
+       * @property {Rotation} rotation
+       */
+      rotation: {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat(),
+        w: reader.readFloat()
+      },
+
+      /**
+       * @property {number} scale
+       */
+      scale: reader.readFloat(),
+
+      /**
+       * @property {PrefabComponents} components
+       */
+      components: readComponents(reader, versions),
+
+      /**
+       * @property {PrefabEntities} entities
+       */
+      entities: readEntities(reader, name, versions),
+
+      /**
+       * @property {PrefabChild[]} children
+       */
+      children: readChildren(reader, versions)
+    });
+  }
+
+  /**
+   * Creates a `Prefab` from reading a `SaveString`.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const saveString = `43430,230,43430,3290698471,1125743666,1132721897,1050703933,3208373430,1039090831,1058493384,1043542835,2290978823,418,3290698471,1125743666,1132721897,1050703933,3208373430,1039090831,1058493384,3221225472,0,0,0,0,0,363610349,2147483736,3005828291,3221225472,2415919104,0,395228240,397619388,393508864,400941080,2546407302,4157020038,3890602430,1579755829,536870916,374086096,2147483844,1610612736,765,2684354569,338752663,2281701377,0,0,19021736,1744830465,67108864,75722752,0,303,67108864,1124073472,0,0,`;
+   *
+   * const prefab = Prefab.fromSaveString<'SpriggullDrumstick_Full_Ripe'>(saveString);
+   */
+  static fromSaveString<TPrefabName extends ATTPrefabName = ATTPrefabName>(
+    saveString: string,
+    options?: BinaryDataOptions
+  ): Prefab<TPrefabName> {
+    if (!BinaryData.isSaveString(saveString)) {
+      throw new Error('SaveString is malformed.');
+    }
+
+    const [dataString, componentVersionsString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined' || dataString.length === 0) throw new Error('SaveString is malformed.');
+
+    const [hashString, dataLengthString, ...unsignedIntegerStrings] = dataString.split(',').filter(Boolean);
+
+    if (
+      typeof hashString === 'undefined' ||
+      typeof dataLengthString === 'undefined' ||
+      unsignedIntegerStrings.length === 0
+    ) {
+      throw new Error('SaveString is malformed.');
+    }
+
+    const unsignedIntegers = unsignedIntegerStrings.map(Number);
+    let componentVersions: Map<number, number> | undefined = undefined;
+
+    if (typeof componentVersionsString !== 'undefined') {
+      componentVersions = new Map<number, number>();
+
+      const [pairCountString, ...versionPairStrings] = componentVersionsString.split(',').filter(Boolean);
+
+      if (typeof pairCountString === 'undefined' || typeof versionPairStrings === 'undefined') {
+        throw new Error('SaveString is malformed.');
+      }
+
+      const expectedCount = Number(pairCountString);
+      const versionPairs = versionPairStrings.map(Number);
+
+      if (expectedCount !== versionPairs.length / 2) {
+        throw new Error(
+          `SaveString contains invalid versioning. Expected ${expectedCount} versions but parsed ${
+            versionPairs.length / 2
+          }.`
+        );
+      }
+
+      let lastHash = 0;
+
+      for (let index = 0; index < expectedCount; ++index) {
+        const isHash = index % 2 === 0;
+
+        if (isHash) {
+          lastHash = Number(versionPairs[index]);
+        } else {
+          componentVersions.set(lastHash, Number(versionPairs[index]));
+        }
+      }
+    }
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers, options).toBinaryString();
+    const reader = new BinaryReader(data);
+
+    return Prefab.fromBinary<TPrefabName>(reader, componentVersions);
+  }
+
+  /**
+   * Gets the spin (vector) on the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Stone'>.fromSaveString('...');
+   *
+   * const angularVelocity = prefab.getAngularVelocity();
+   * const { x, y, z } = angularVelocity;
+   */
+  getAngularVelocity(): Velocity {
+    return this.components.NetworkRigidbody?.angularVelocity ?? { x: 0, y: 0, z: 0 };
+  }
+
+  /**
+   * Finds the first child prefab matching the given name. If there are multiple child prefabs with
+   * the same name, you can use the second argument to provide a parent hash to match against.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * prefab.addChildPrefab('Slot_Large_SwordType_Craft_6134', new Prefab('Guard'));
+   *
+   * const childGuard = prefab.getChildPrefab('Guard');
+   * // `childGuard` is an instance of `Prefab<'Guard'>`
+   *
+   * const childPommel = prefab.getChildPrefab('Pommel');
+   * // `childPommel` is `undefined`
+   */
+  getChildPrefab<TChildPrefabName extends ATTPrefabName>(
+    prefabName: TChildPrefabName,
+    parentHash?: number
+  ): Prefab<TChildPrefabName> | undefined {
+    const child = this.children.find(child =>
+      child.prefab.name === prefabName && typeof parentHash === 'undefined' ? true : child.parentHash === parentHash
+    );
+
+    if (typeof child === 'undefined') return undefined;
+
+    return child.prefab as Prefab<TChildPrefabName>;
+  }
+
+  /**
+   * Gets a map of component hashes and the versions used on this prefab. Will throw an error if the
+   * prefab uses mixed versions of a particular component.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const componentVersions = prefab.getComponentVersions();
+   */
+  getComponentVersions(): Map<number, number> {
+    const versions = new Map<number, number>();
+
+    function setComponentVersion(hash: number, version: number): ReturnType<Map<number, number>['set']> {
+      const storedVersion = versions.get(hash);
+
+      if (typeof storedVersion !== 'undefined' && storedVersion !== version) {
+        throw new Error(
+          `Component ${hash} exists with version ${storedVersion} and ${version}. All instances of a component must exist with the same version.`
+        );
+      }
+
+      return versions.set(hash, version);
+    }
+
+    /* Get component versions from prefab components. */
+    for (const component of Object.values(this.components)) {
+      if (Array.isArray(component)) {
+        for (const unknownComponent of component) {
+          setComponentVersion(unknownComponent.hash, unknownComponent.version);
+        }
+      } else {
+        setComponentVersion(component.hash, component.version);
+      }
+    }
+
+    /* Get component versions from prefab entities. */
+    for (const entity of Object.values(this.entities) as Entity<TPrefabName>[]) {
+      for (const component of Object.values(entity.components)) {
+        if (Array.isArray(component)) {
+          for (const unknownComponent of component) {
+            setComponentVersion(unknownComponent.hash, unknownComponent.version);
+          }
+        } else {
+          setComponentVersion(component.hash, component.version);
+        }
+      }
+    }
+
+    /* Get component versions from child prefabs. */
+    for (const { prefab } of this.children) {
+      const componentVersions = prefab.getComponentVersions();
+
+      for (const [hash, version] of componentVersions.entries()) {
+        setComponentVersion(hash, version);
+      }
+    }
+
+    return versions;
+  }
+
+  /**
+   * Gets the gift sender's name, which is labeled on the gift.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Gift_Mail_Box'>.fromSaveString('...');
+   *
+   * const giftBoxLabel = prefab.getGiftBoxLabel();
+   */
+  getGiftBoxLabel(): string {
+    return this.components.SentGift?.senderName ?? '';
+  }
+
+  /**
+   * Gets the prefab's physical integrity.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const integrity = prefab.getIntegrity();
+   */
+  getIntegrity(): number {
+    return this.components.DurabilityModule?.integrity ?? 1;
+  }
+
+  /**
+   * Gets the {@link https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html kinematic}
+   * state of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const isKinematic = prefab.getKinematic();
+   */
+  getKinematic(): boolean {
+    return this.components.NetworkRigidbody?.isKinematic ?? false;
+  }
+
+  /**
+   * Gets the prefab's physical material.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { PhysicalMaterialPartHash, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Guard'>.fromSaveString('...');
+   *
+   * const materialHash = prefab.getMaterial();
+   * const materialName = PhysicalMaterialPartHash[materialHash];
+   */
+  getMaterial(): PhysicalMaterialPartHash {
+    return this.components.PhysicalMaterialPart?.materialHash ?? 0;
+  }
+
+  /**
+   * Gets the burning state of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Grass_Clump'>.fromSaveString('...');
+   *
+   * const isOnFire = prefab.getOnFire();
+   */
+  getOnFire(): boolean {
+    const fireEntity = Object.values(this.entities).find(entity => entity.name === 'Fire');
+
+    return fireEntity?.components.HeatSourceBase?.isLit ?? false;
+  }
+
+  /**
+   * Gets the position of the prefab. If the prefab is a child of another prefab, then this position
+   * is local to that parent. Otherwise, this position is in world space.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const position = prefab.getPosition();
+   * const { x, y, z } = position;
+   */
+  getPosition(): Position {
+    return this.position;
+  }
+
+  /**
+   * Gets the rotation of the prefab. If the prefab is a child of another prefab, then this rotation
+   * is local to that parent. Otherwise, this rotation is in world space.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const rotation = prefab.getRotation();
+   * const { x, y, z, w } = rotation;
+   */
+  getRotation(): Rotation {
+    return this.rotation;
+  }
+
+  /**
+   * Gets the scale of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const scale = prefab.getScale();
+   */
+  getScale(): number {
+    return this.scale;
+  }
+
+  /**
+   * Gets the {@link https://docs.unity3d.com/Manual/RigidbodiesOverview.html sleeping}
+   * state of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * const isServerSleeping = prefab.getServerSleeping();
+   */
+  getServerSleeping(): boolean {
+    return this.components.NetworkRigidbody?.isServerSleeping ?? false;
+  }
+
+  /**
+   * Gets the number of servings on a liquid container prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Potion_Medium'>.fromSaveString('...');
+   *
+   * const servings = prefab.getServings();
+   */
+  getServings(): number {
+    return this.components.LiquidContainer?.contentLevel ?? 0;
+  }
+
+  /**
+   * Gets the name of the spawn area population, if there is one. Returns `undefined` otherwise.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Disk_Encounter'>.fromSaveString('...');
+   *
+   * const populationName = prefab.getSpawnAreaPopulationName();
+   */
+  getSpawnAreaPopulationName(): 'Unknown' | PopulationDefinitionName | undefined {
+    const populationDefinitionHash = this.components.PopulationSpawnArea?.definition as
+      | PopulationDefinitionHash
+      | undefined;
+    const populationDefinitionName =
+      typeof populationDefinitionHash === 'undefined'
+        ? undefined
+        : (PopulationDefinitionHash[populationDefinitionHash] as PopulationDefinitionName | undefined) ?? 'Unknown';
+
+    return populationDefinitionName;
+  }
+
+  /**
+   * Gets the direction (vector) on the prefab. Units are in metres per second.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Stone'>.fromSaveString('...');
+   *
+   * const velocity = prefab.getVelocity();
+   * const { x, y, z } = velocity;
+   */
+  getVelocity(): Velocity {
+    return this.components.NetworkRigidbody?.velocity ?? { x: 0, y: 0, z: 0 };
+  }
+
+  /**
+   * Prints this prefab's data structure to the console.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.inspect();
+   */
+  inspect(): this {
+    process.stdout.write(`${inspect(this, false, null)}\n`);
+
+    return this;
+  }
+
+  /**
+   * Prints this prefab's `SaveString` to the console.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.print();
+   */
+  print(): this {
+    const saveString = this.toSaveString();
+    process.stdout.write(`${saveString}\n`);
+
+    return this;
+  }
+
+  /**
+   * Removes all child `Prefab` from this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.removeAllChildPrefabs();
+   */
+  removeAllChildPrefabs(): this {
+    this.children = [];
+
+    return this;
+  }
+
+  /**
+   * Removes all components on this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.removeAllComponents();
+   */
+  removeAllComponents(): this {
+    this.components = { Unknown: [] };
+
+    return this;
+  }
+
+  /**
+   * Removes all entities on this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.removeAllEntities();
+   */
+  removeAllEntities(): this {
+    this.entities = {};
+
+    return this;
+  }
+
+  /**
+   * Removes all gift `Prefab` from this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Gift_Mail_Box'>.fromSaveString('...');
+   *
+   * prefab.removeAllGifts();
+   */
+  removeAllGifts(): this {
+    const sentGiftComponent = this.components.SentGift;
+
+    if (typeof sentGiftComponent !== 'undefined') {
+      sentGiftComponent.gifts = [];
+    }
+
+    return this;
+  }
+
+  /**
+   * Removes the specified child `Prefab` from this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.removeChildPrefab(51672);
+   * // or
+   * prefab.removeChildPrefab('Guard');
+   */
+  removeChildPrefab(prefabHash: ATTPrefabHash): this;
+  removeChildPrefab(prefabName: ATTPrefabName): this;
+  removeChildPrefab(prefabArg: ATTPrefabHash | ATTPrefabName): this {
+    if (typeof prefabArg === 'undefined') {
+      throw new Error('You must pass a child prefab hash or name to remove from this prefab.');
+    }
+
+    const key = typeof prefabArg === 'number' ? 'hash' : 'name';
+
+    this.children = [...this.children.filter(child => child.prefab[key] !== prefabArg)];
+
+    return this;
+  }
+
+  /**
+   * Removes the specified component from this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { ComponentHash, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.removeComponent(ComponentHash.NetworkRigidbody);
+   * // or
+   * prefab.removeComponent('NetworkRigidbody');
+   */
+  removeComponent(componentHash: ComponentHash): this;
+  removeComponent(componentName: keyof Omit<PrefabComponents, 'Unknown'>): this;
+  removeComponent(componentArg: ComponentHash | keyof Omit<PrefabComponents, 'Unknown'>): this {
+    if (typeof componentArg === 'undefined') {
+      throw new Error('You must pass a component hash or name to remove from this prefab.');
+    }
+
+    const componentName =
+      typeof componentArg === 'string'
+        ? componentArg
+        : (ComponentHash[componentArg] as keyof typeof ComponentHash | undefined);
+
+    if (typeof componentName === 'undefined') {
+      for (const component of Object.values(this.components)) {
+        if (Array.isArray(component)) {
+          this.components.Unknown = component.filter(unknownComponent => unknownComponent.hash !== componentArg);
+        } else if (component.hash === componentArg) {
+          delete this.components[component.name as keyof Omit<PrefabComponents, 'Unknown'>];
+        }
+      }
+    } else {
+      if (componentName in this.components) {
+        delete this.components[componentName];
+      } else {
+        const unknownComponentIndex = this.components.Unknown.findIndex(component => component.name === componentArg);
+
+        if (unknownComponentIndex > -1) {
+          this.components.Unknown = this.components.Unknown.toSpliced(unknownComponentIndex, 1);
+        }
+      }
+    }
+
+    return this;
+  }
+
+  /**
+   * Removes the specified entity from this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Handle_Short'>.fromSaveString('...');
+   *
+   * prefab.removeEntity('Slot_Multi_6136');
+   */
+  removeEntity(entityKey: Exclude<EntityKey<TPrefabName>, 'Unknown'>): this {
+    if (typeof entityKey === 'undefined') {
+      throw new Error('You must pass an entity name to remove from this prefab.');
+    }
+
+    delete this.entities[entityKey];
+
+    return this;
+  }
+
+  /**
+   * Removes the specified gift `Prefab` from this prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Gift_Mail_Box'>.fromSaveString('...');
+   *
+   * prefab.removeGift(31326);
+   * // or
+   * prefab.removeGift('Dynamite');
+   */
+  removeGift(prefabHash: ATTPrefabHash): this;
+  removeGift(prefabName: ATTPrefabName): this;
+  removeGift(prefabArg: ATTPrefabHash | ATTPrefabName): this {
+    if (typeof prefabArg === 'undefined') {
+      throw new Error('You must pass a gift prefab hash or name to remove from this prefab.');
+    }
+
+    const hash =
+      typeof prefabArg === 'number' ? prefabArg : (ATTPrefabs[prefabArg]?.hash as ATTPrefabHash | undefined) ?? 0;
+
+    const sentGiftComponent = this.components.SentGift;
+
+    if (typeof sentGiftComponent !== 'undefined') {
+      sentGiftComponent.gifts = [...sentGiftComponent.gifts.filter(gift => gift?.hash !== hash)];
+    }
+
+    return this;
+  }
+
+  /**
+   * Removes the spawn area components from the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = Prefab<'Disk_Encounter'>.fromSaveString('...');
+   *
+   * prefab.removeSpawnArea();
+   */
+  removeSpawnArea(): this {
+    delete this.components.PopulationSpawnArea;
+    delete this.components.SpawnArea;
+
+    return this;
+  }
+
+  /**
+   * Sets a spin (vector) on the prefab, causing the physics engine to apply a force to it when
+   * spawning. Units are in metres per second. Only works reliably on the parent prefab. Does not
+   * work on kinematic prefabs. Does not work on static prefabs.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * prefab.setAngularVelocity({ x: 420, y: 69, z: 1337 });
+   */
+  setAngularVelocity({ x, y, z }: AngularVelocity): this {
+    if (isSavableComponent('NetworkRigidbody', this.name)) {
+      const version = this.components.NetworkRigidbody?.version ?? FALLBACK_NETWORK_RIGIDBODY_VERSION;
+      const angularVelocity: AngularVelocity = { x, y, z };
+
+      this.components.NetworkRigidbody = new NetworkRigidbodyComponent({
+        ...this.components.NetworkRigidbody,
+        version,
+        angularVelocity
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the gift sender's name, which is labeled on the gift.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Gift_Mail_Box');
+   *
+   * prefab.setGiftBoxLabel('topkek');
+   */
+  setGiftBoxLabel(label: string): this {
+    if (typeof label === 'undefined') {
+      throw new Error('You must pass a string to set as the gift box label.');
+    }
+
+    if (isSavableComponent('SentGift', this.name)) {
+      const version = this.components.SentGift?.version ?? FALLBACK_SENT_GIFT_VERSION;
+
+      this.components.SentGift = new SentGiftComponent({
+        ...this.components.SentGift,
+        version,
+        senderName: label
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the prefab's integrity. This can change both its appearance and other qualities such as
+   * durability and the amount of materials recovered from recycling.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * prefab.setIntegrity(0.69);
+   */
+  setIntegrity(integrity: number): this {
+    if (typeof integrity === 'undefined') {
+      throw new Error('You must pass a number to set as the integrity.');
+    }
+
+    if (isSavableComponent('DurabilityModule', this.name)) {
+      const version = this.components.DurabilityModule?.version ?? FALLBACK_DURABILITY_MODULE_VERSION;
+
+      this.components.DurabilityModule = new DurabilityModuleComponent({
+        ...this.components.DurabilityModule,
+        version,
+        integrity
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Makes the prefab {@link https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html kinematic}.
+   * By default, a `new Prefab()` is not kinematic, but some prefabs require to be kinematic to work
+   * properly. You can optionally pass a boolean, for example `prefab.setKinematic(false)`.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * prefab.setKinematic(true);
+   */
+  setKinematic(isKinematic?: boolean): this {
+    if (isSavableComponent('NetworkRigidbody', this.name)) {
+      const version = this.components.NetworkRigidbody?.version ?? FALLBACK_NETWORK_RIGIDBODY_VERSION;
+
+      this.components.NetworkRigidbody = new NetworkRigidbodyComponent({
+        ...this.components.NetworkRigidbody,
+        version,
+        isKinematic: isKinematic ?? true
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the prefab's physical material. This can change both its appearance and other qualities such
+   * as durability, damage, heat retention and weight.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { PhysicalMaterialPartHash, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * prefab.setMaterial(PhysicalMaterialPartHash.Mythril);
+   * // or
+   * prefab.setMaterial('Mythril');
+   */
+  setMaterial(materialHash: PhysicalMaterialPartHash): this;
+  setMaterial(materialName: keyof typeof PhysicalMaterialPartHash): this;
+  setMaterial(materialArg: PhysicalMaterialPartHash | keyof typeof PhysicalMaterialPartHash): this {
+    if (typeof materialArg === 'undefined') {
+      throw new Error('You must pass a PhysicalMaterialPartHash to set as the material.');
+    }
+
+    if (isSavableComponent('PhysicalMaterialPart', this.name)) {
+      const version = this.components.PhysicalMaterialPart?.version ?? FALLBACK_PHYSICAL_MATERIAL_PART_VERSION;
+      const materialHash = typeof materialArg === 'number' ? materialArg : PhysicalMaterialPartHash[materialArg];
+
+      this.components.PhysicalMaterialPart = new PhysicalMaterialPartComponent({
+        ...this.components.PhysicalMaterialPart,
+        version,
+        materialHash
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the prefab on fire, if it is capable of catching fire.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Grass_Clump');
+   *
+   * prefab.setOnFire(true);
+   */
+  setOnFire(isLit?: boolean): this {
+    const validFireEntity = Object.values<{
+      hash: number;
+      name: string;
+      savables: Record<string, { hash: number; name: string }>;
+    }>(ATTPrefabs[this.name].embedded).find(entity => {
+      return Object.values(entity.savables).some(savable => ['Fire', 'FireDissolve'].includes(savable.name));
+    });
+
+    if (typeof validFireEntity !== 'undefined') {
+      const currentFireEntity = Object.values(this.entities).find(entity => entity.name === validFireEntity.name);
+      const version = currentFireEntity?.components.HeatSourceBase?.version ?? FALLBACK_HEAT_SOURCE_BASE_VERSION;
+      const key = `${validFireEntity.name}_${validFireEntity.hash}` as EntityKey<TPrefabName>;
+
+      this.entities[key] = new Entity<TPrefabName>(key as keyof (typeof ATTPrefabs)[TPrefabName]['embedded'], {
+        hash: validFireEntity.hash,
+        isAlive: true,
+        components: {
+          ...currentFireEntity?.components,
+          HeatSourceBase: new HeatSourceBaseComponent({
+            version,
+            isLit: isLit ?? true
+          })
+        }
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the position of the prefab. If the prefab is a child of another prefab, then this position
+   * is local to that parent. Otherwise, this position is in world space.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * prefab.setPosition({ x: 420, y: 69, z: 1337 });
+   */
+  setPosition({ x, y, z }: Position): this {
+    const position: Position = { x, y, z };
+    this.position = position;
+
+    if (isSavableComponent('NetworkRigidbody', this.name)) {
+      const version = this.components.NetworkRigidbody?.version ?? FALLBACK_NETWORK_RIGIDBODY_VERSION;
+
+      this.components.NetworkRigidbody = new NetworkRigidbodyComponent({
+        ...this.components.NetworkRigidbody,
+        version,
+        position
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the rotation of the prefab. If the prefab is a child of another prefab, then this rotation
+   * is local to that parent. Otherwise, this rotation is in world space.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * prefab.setRotation({ x: 0.42, y: -0.69, z: 0.1337, w: -0.88 });
+   */
+  setRotation({ x, y, z, w }: Rotation): this {
+    const rotation: Rotation = { x, y, z, w };
+    this.rotation = rotation;
+
+    if (isSavableComponent('NetworkRigidbody', this.name)) {
+      const version = this.components.NetworkRigidbody?.version ?? FALLBACK_NETWORK_RIGIDBODY_VERSION;
+
+      this.components.NetworkRigidbody = new NetworkRigidbodyComponent({
+        ...this.components.NetworkRigidbody,
+        version,
+        rotation
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the scale of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * prefab.setScale(0.69);
+   */
+  setScale(scale: number): this {
+    if (typeof scale === 'undefined') {
+      throw new Error('You must pass a number to set as the scale.');
+    }
+
+    this.scale = scale;
+
+    return this;
+  }
+
+  /**
+   * Makes the prefab {@link https://docs.unity3d.com/Manual/RigidbodiesOverview.html sleep}.
+   * By default, a `new Prefab()` is not sleeping. A sleeping prefab does not have its physics
+   * simulated until it receives a collision or force, such as touching it. You can optionally pass
+   * a boolean, for example `prefab.setServerSleeping(false)`.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Handle_Short');
+   *
+   * prefab.setServerSleeping(true);
+   */
+  setServerSleeping(isServerSleeping?: boolean): this {
+    if (isSavableComponent('NetworkRigidbody', this.name)) {
+      const version = this.components.NetworkRigidbody?.version ?? FALLBACK_NETWORK_RIGIDBODY_VERSION;
+
+      this.components.NetworkRigidbody = new NetworkRigidbodyComponent({
+        ...this.components.NetworkRigidbody,
+        version,
+        isServerSleeping: isServerSleeping ?? true
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets the number of servings on a liquid container prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Potion_Medium');
+   *
+   * prefab.setServings(69);
+   */
+  setServings(servings: number): this {
+    if (typeof servings === 'undefined') {
+      throw new Error('You must pass a number to set as the amount of servings.');
+    }
+
+    if (isSavableComponent('LiquidContainer', this.name)) {
+      const version = this.components.LiquidContainer?.version ?? FALLBACK_LIQUID_CONTAINER_VERSION;
+
+      this.components.LiquidContainer = new LiquidContainerComponent({
+        ...this.components.LiquidContainer,
+        version,
+        contentLevel: Math.max(0, Math.ceil(servings)),
+        hasContent: Math.ceil(servings) > 0
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets a spawn area on the prefab with the given population and any additional configuration.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { PopulationDefinitionHash, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Disk_Encounter');
+   *
+   * prefab.setSpawnArea(PopulationDefinitionHash.WyrmPopulation, {
+   *   currentPopulation: 5,
+   *   isOneOff: false,
+   *   isPopulationStarted: true,
+   *   maxPopulation: 20,
+   *   numberOfSpawnPoints: 40,
+   *   size: 5,
+   *   startingPopulation: 5
+   * });
+   */
+  setSpawnArea(populationDefinitionHash: PopulationDefinitionHash, props?: SetSpawnAreaProps): this;
+  setSpawnArea(populationDefinitionName: PopulationDefinitionName, props?: SetSpawnAreaProps): this;
+  setSpawnArea(
+    populationDefinitionArg: PopulationDefinitionHash | PopulationDefinitionName,
+    props: SetSpawnAreaProps = {}
+  ): this {
+    if (typeof populationDefinitionArg === 'undefined') {
+      throw new Error('You must pass a population definition hash or name to set on this spawn area.');
+    }
+
+    if (isSavableComponent('PopulationSpawnArea', this.name) && isSavableComponent('SpawnArea', this.name)) {
+      const populationDefinitionHash =
+        typeof populationDefinitionArg === 'number'
+          ? populationDefinitionArg
+          : PopulationDefinitionHash[populationDefinitionArg];
+
+      this.components.PopulationSpawnArea = new PopulationSpawnAreaComponent({
+        ...this.components.PopulationSpawnArea,
+        version: this.components.PopulationSpawnArea?.version ?? FALLBACK_POPULATION_SPAWN_AREA_VERSION,
+        definition: populationDefinitionHash,
+        isPopulationStarted: props.isPopulationStarted,
+        maxPopulation: props.maxPopulation,
+        currentPopulation: props.currentPopulation,
+        numberOfSpawnPoints: props.numberOfSpawnPoints,
+        startingPopulation: props.startingPopulation,
+        isOneOff: props.isOneOff
+      });
+
+      this.components.SpawnArea = new SpawnAreaComponent({
+        ...this.components.SpawnArea,
+        version: this.components.SpawnArea?.version ?? FALLBACK_SPAWN_AREA_VERSION,
+        size: props.size
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Sets a direction (vector) on the prefab, causing the physics engine to apply a force to it when
+   * spawning. Units are in metres per second. Only works reliably on the parent prefab. Does not work
+   * on kinematic prefabs. Does not work on static prefabs.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * prefab.setVelocity({ x: 420, y: 69, z: 1337 });
+   */
+  setVelocity({ x, y, z }: Velocity): this {
+    if (isSavableComponent('NetworkRigidbody', this.name)) {
+      const version = this.components.NetworkRigidbody?.version ?? FALLBACK_NETWORK_RIGIDBODY_VERSION;
+      const velocity: Velocity = { x, y, z };
+
+      this.components.NetworkRigidbody = new NetworkRigidbodyComponent({
+        ...this.components.NetworkRigidbody,
+        version,
+        velocity
+      });
+    }
+
+    return this;
+  }
+
+  /**
+   * Returns a `BinaryString` representation of the prefab.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { ComponentHash, Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * const componentVersions = prefab.getComponentVersions();
+   * // or
+   * const componentVersions = new Map<number, number>([
+   *   [ComponentHash.NetworkRigidbody, 1],
+   *   [ComponentHash.PhysicalMaterialPart, 1],
+   *   [ComponentHash.Pickup, 2]
+   *   // etc...
+   * ]);
+   *
+   * const binaryString = prefab.toBinary(componentVersions);
+   */
+  toBinary(componentVersions: Map<number, number>): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} hash
+     */
+    writer.writeUnsignedInteger(this.hash);
+
+    /**
+     * @property {Position} position
+     */
+    writer.writeFloat(this.position.x);
+    writer.writeFloat(this.position.y);
+    writer.writeFloat(this.position.z);
+
+    /**
+     * @property {Rotation} rotation
+     */
+    writer.writeFloat(this.rotation.x);
+    writer.writeFloat(this.rotation.y);
+    writer.writeFloat(this.rotation.z);
+    writer.writeFloat(this.rotation.w);
+
+    /**
+     * @property {float} scale
+     */
+    writer.writeFloat(this.scale);
+
+    /**
+     * @property {PrefabComponents} components
+     */
+    writeComponents(writer, this.components, componentVersions);
+
+    /**
+     * @property {PrefabEntities} entities
+     */
+    writeEntities(writer, this.entities, componentVersions);
+
+    /**
+     * @property {PrefabChild[]} children
+     */
+    writeChildren(writer, this.children, componentVersions);
+
+    return writer.flush();
+  }
+
+  /**
+   * Returns the `SaveString` to spawn this prefab in the game. You may pass additional options to
+   * change the output behaviour.
+   *
+   * @since v3.0.0
+   *
+   * @example
+   * import { Prefab } from 'att-string-transcoder';
+   *
+   * const prefab = new Prefab('Stone');
+   *
+   * const saveString = prefab.toSaveString();
+   */
+  toSaveString(options: ToSaveStringOptions = {}): SaveString {
+    const componentVersions = this.getComponentVersions();
+    const data = this.toBinary(componentVersions);
+
+    const hasIndeterminateVersions = [...componentVersions.values()].includes(0);
+
+    if (hasIndeterminateVersions && !options.ignoreIndeterminateComponentVersions) {
+      throw new Error(
+        'Prefab contains components with version `0`. Current in-game versions for those components are not available. The produced save string will not contain component versions and may not be spawnable in-game.\n\nYou may call `.toSaveString(true)` to force producing a save string with this limitation.\n'
+      );
+    }
+
+    /* Pad bits with trailing zeroes to make it % 32. */
+    const roundedUpDataLength = data.length + (32 - (data.length % 32 === 0 ? 32 : data.length % 32));
+    const paddedData = data.padEnd(roundedUpDataLength, '0');
+
+    /* Calculate byte size of padded binary. */
+    const bytes = paddedData.length / 8;
+
+    /* Convert binary to array of unsigned integers. */
+    const unsignedIntegers = new BinaryData(paddedData).toUnsignedIntegerArray();
+
+    /* Construct the binary data string. */
+    const binaryDataString = [this.hash, bytes, ...unsignedIntegers].join(',');
+
+    /* Construct the versions string. */
+    let componentVersionsString: string | undefined;
+
+    if (!hasIndeterminateVersions && componentVersions.size > 0) {
+      componentVersionsString = `${componentVersions.size},${[...componentVersions.entries()].map(
+        ([componentHash, componentVersion]) => `${componentHash},${componentVersion}`
+      )}`;
+    }
+
+    /* Return SaveString. */
+    const strings = [binaryDataString, !options.excludeComponentVersions && componentVersionsString].filter(Boolean);
+    return `${strings.join(',|')},` as SaveString;
+  }
+}
diff --git a/src/PrefabEmbeddedEntityHash.ts b/src/PrefabEmbeddedEntityHash.ts
deleted file mode 100644
index 889ed2d..0000000
--- a/src/PrefabEmbeddedEntityHash.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-export const PrefabEmbeddedEntityHash: {
-  [prefab: string]: {
-    [embeddedEntity: string]: number;
-  };
-} = {
-  Woodcut_B0_B0: { Top: 8056 },
-  Woodcut_B0_B0_S15: { Top: 53706, Stick: 53710 },
-  Woodcut_B0_B15_B30: { Branch_1: 20342, Branch_2: 20338 },
-  Woodcut_B0_S0_S30: { Stick_1: 38940, Stick_2: 38936 },
-  Woodcut_B15_B15: { Top: 4690 },
-  Woodcut_B30_B30: { Top: 58002 },
-  Woodcut_B5_B5: { Top: 37822 },
-  Woodcut_BranchRoot_V1_B0: { Top: 14282 },
-  Woodcut_BranchRoot_V1_B15_S30: { Top: 63620, Branch: 63622 },
-  Woodcut_Leaves_V1_L_F: {},
-  Woodcut_Leaves_V1_L_S: {},
-  Woodcut_Leaves_V1_S_F: {},
-  Woodcut_Leaves_V1_S_S: {},
-  Woodcut_Leaves_V2_D: {},
-  Woodcut_Leaves_V2_L: {},
-  Woodcut_Leaves_V2_Topper: {},
-  Woodcut_Root_V1_T0: { Top: 49314 },
-  Woodcut_Root_V1_T0_B15: { Top: 23584, Branch: 12832 },
-  Woodcut_Root_V1_T0_S30: { Top: 56452, Stick: 51558 },
-  Woodcut_Root_V1_T30: { Top: 7658 },
-  Woodcut_S0_S0: { Top: 1286 },
-  Woodcut_S0_S15_S15: { Top_1: 2062, Top_2: 60778 },
-  Woodcut_T0_B0_B30: { Branch_1: 4000, Branch_2: 3996 },
-  Woodcut_T0_B15_B30: { Branch_1: 634, Branch_2: 636 },
-  Woodcut_T0_T0: { Top: 39100 },
-  Woodcut_T0_T0_B30: { Top: 34360, Branch: 34356 },
-  Woodcut_T0_T0_B45: { Top: 15160, Branch: 15162 },
-  Woodcut_T0_T0_S30: { Top: 45916, Stick: 45912 },
-  Woodcut_T0_T0_S30_S30_S30: { Top: 836, Stick_1: 34724, Stick_2: 17522, Stick_3: 910 },
-  Woodcut_T15_T15: { Top: 30734 },
-  Woodcut_T30_T30: { Top: 28372 },
-  Woodcut_T5_T5: { Top: 32750 }
-};
diff --git a/src/PrefabHash.ts b/src/PrefabHash.ts
deleted file mode 100644
index 6980f0c..0000000
--- a/src/PrefabHash.ts
+++ /dev/null
@@ -1,880 +0,0 @@
-export enum PrefabHash {
-  And = 42422,
-  Anvil = 23182,
-  Anvil_Training = 24218,
-  Apple_Core_Burnt = 50484,
-  Apple_Core_Cooked = 15500,
-  Apple_Core_Ripe = 902,
-  Apple_Core_Unripe = 31614,
-  Apple_Full_Burnt = 62102,
-  Apple_Full_Cooked = 14844,
-  Apple_Full_Ripe = 40010,
-  Apple_Full_Unripe = 6740,
-  Apple_Half_Burnt = 65526,
-  Apple_Half_Cooked = 2000,
-  Apple_Half_Ripe = 7278,
-  Apple_Half_Unripe = 62012,
-  Apple_Tree = 61222,
-  Apple_Tree_Separated = 8974,
-  Arrow = 56460,
-  Arrow_Light_Beam_Effect = 1798,
-  Arrow_Shaft_Wooden = 29772,
-  Arrow_Shaft_Wooden_Training = 36772,
-  Arrow_Training = 36190,
-  Arrow_Training_Dud = 8858,
-  Ash_Pile = 53398,
-  Ash_Gotera_Smoke = 48860,
-  Ash_Tree_Seed = 35274,
-  Assembly_Deck = 17520,
-  ATM_Coin_Bank = 9780,
-  Auto_Cam_Player = 61644,
-  Axe_Head = 34412,
-  Axe_Head_Curve = 50322,
-  Axe_Head_Felling = 9918,
-  Axe_Head_GreatCurve = 10056,
-  Axe_Head_LShape = 17400,
-  Axe_Training = 57010,
-  Babu_Leg_Bone = 32526,
-  Babu_Leg_Full_Burnt = 64844,
-  Babu_Leg_Full_Cooked = 42916,
-  Babu_Leg_Full_Ripe = 2562,
-  Babu_Leg_Half_Burnt = 50328,
-  Babu_Leg_Half_Cooked = 50326,
-  Babu_Leg_Half_Ripe = 50252,
-  Bag = 35324,
-  Basic_Population_Folder = 31116,
-  Birch_Tree_Seed = 55274,
-  Blue_Mix_Recipe_Burnt_Stew = 57666,
-  Blue_Mix_Recipe_Cooked_Stew = 57642,
-  Blue_Mix_Recipe_Raw_Stew = 57614,
-  Blueberry_Full_Burnt = 49890,
-  Blueberry_Full_Cooked = 47468,
-  Blueberry_Full_Ripe = 45012,
-  Blueberry_Full_Unripe = 42556,
-  Blueberry_Recipe_Burnt_Stew = 36830,
-  Blueberry_Recipe_Cooked_Stew = 36086,
-  Blueberry_Recipe_Raw_Stew = 35338,
-  Blueberry_Tree = 878,
-  Blueberry_Tree_Separated = 13784,
-  Book = 44174,
-  Bookshelf = 64316,
-  Bookshelf_NoBackboard = 59952,
-  Bought_Skill_Orb_Replacer = 42842,
-  Boulder_Button_Spawner = 21830,
-  Bow = 56546,
-  Bow_Blade = 27416,
-  Bow_Training = 42340,
-  Breakable_Box = 19624,
-  Breakable_Pot = 60800,
-  Breakable_Root_Bendy = 41482,
-  Breakable_Root_Curved = 64388,
-  Breakable_Root_Fence = 62846,
-  Breakable_Root_Ground_01 = 34014,
-  Breakable_Root_Ground_02 = 23246,
-  Breakable_Root_Ground_03 = 21206,
-  Breakable_Root_Ground_04 = 18702,
-  Breakable_Root_Ground_05 = 16298,
-  Breakable_Root_Ground_06 = 13634,
-  Breakable_Root_Hanging_Bendy = 63792,
-  Breakable_Root_Hanging_Column_01 = 37666,
-  Breakable_Root_Hanging_Column_02 = 24548,
-  Breakable_Root_Hanging_Straight = 12714,
-  Breakable_Root_Hanging_Thin_Bendy = 6394,
-  Breakable_Root_Hanging_Thin_Straight = 57168,
-  Breakable_Root_HangingShort_Bendy = 13856,
-  Breakable_Root_HangingShort_Curved = 12224,
-  Breakable_Root_HangingShort_Straight = 9226,
-  Breakable_Root_HangingShort_Wavy = 8534,
-  Breakable_Root_Mound_Large = 15602,
-  Breakable_Root_Mound_Small = 43010,
-  Breakable_Root_Straight = 47012,
-  Breakable_Root_Wavy = 28332,
-  Broken_Box_Piece = 260,
-  Broken_Breakable_Root_Piece_Ground = 43996,
-  Broken_Breakable_Root_Piece_Short = 43998,
-  Broken_Breakable_Root_Piece_Thick = 43994,
-  Broken_Breakable_Root_Piece_Thin = 44000,
-  Broken_Burnable_Root_Piece_Ground = 60406,
-  Broken_Burnable_Root_Piece_Short = 58460,
-  Broken_Burnable_Root_Piece_Thick = 64302,
-  Broken_Burnable_Root_Piece_Thin = 61492,
-  Broken_Crystal_Piece_01 = 60484,
-  Broken_Crystal_Piece_02 = 49198,
-  Broken_Crystal_Piece_03 = 37046,
-  Broken_Crystal_Piece_04 = 23220,
-  Broken_ExplosionBoulder_Part_01 = 45514,
-  Broken_ExplosionBoulder_Part_02 = 45518,
-  Broken_ExplosionBoulder_Part_03 = 45516,
-  Broken_ExplosionBoulder_Part_04 = 45512,
-  Broken_ExplosionBoulder_Part_05 = 45520,
-  Broken_Vine_Bunch_Dead_Piece = 7264,
-  Bronze_Alloy_Ingot = 26316,
-  Brown_Mushroom_Shield = 17258,
-  Bung = 8050,
-  Buried_Pullup = 61742,
-  Burnable_Root_Fence = 45144,
-  Burnable_Root_Ground_01 = 5702,
-  Burnable_Root_Ground_02 = 34852,
-  Burnable_Root_Ground_03 = 65260,
-  Burnable_Root_Ground_04 = 36342,
-  Burnable_Root_Ground_05 = 35154,
-  Burnable_Root_Ground_06 = 37414,
-  Burnable_Root_Hanging_Bendy = 44884,
-  Burnable_Root_Hanging_Column_01 = 39694,
-  Burnable_Root_Hanging_Column_02 = 14166,
-  Burnable_Root_Hanging_Straight = 39592,
-  Burnable_Root_Hanging_Thin_Bendy = 64866,
-  Burnable_Root_Hanging_Thin_Straight = 36356,
-  Burnable_Root_HangingShort_Bendy = 58042,
-  Burnable_Root_HangingShort_Curved = 29008,
-  Burnable_Root_HangingShort_Straight = 43200,
-  Burnable_Root_HangingShort_Wavy = 680,
-  Burnable_Root_Mound_Large = 48874,
-  Burnable_Root_Mound_Small = 17066,
-  Burnable_VineBunch = 35828,
-  Burnable_VineBunch_Tutorial = 38202,
-  Button_Spawner = 42752,
-  cam = 8760,
-  Campfire = 63848,
-  Campfire_Infinite = 63034,
-  Campfire_Weak = 9276,
-  Candy_Cane = 27314,
-  Candy_Cane_Knife = 7676,
-  Carrot_Full_Burnt = 62634,
-  Carrot_Full_Cooked = 60742,
-  Carrot_Full_Ripe = 58838,
-  Carrot_Full_Unripe = 56934,
-  Carrot_Half_Burnt = 64146,
-  Carrot_Half_Cooked = 63758,
-  Carrot_Half_Ripe = 63354,
-  Carrot_Half_Unripe = 62950,
-  Carrot_Leaves = 10440,
-  Carsi_Ingot = 60868,
-  Carved_Pumpkin_Smelter = 27322,
-  Cast_Iron_Lamp = 24782,
-  Cauldron_Medium = 45082,
-  Cave_Explosion_Boulder = 31136,
-  Cave_Explosion_Boulder_Clusters = 17608,
-  Cave_Grass = 63846,
-  Cave_Layer_Chunk = 61672,
-  Cave_Layer_Generation = 61664,
-  Cave_Surface_Teleporter_Ruins = 43368,
-  Cave_Teleporter = 27074,
-  Cave_Teleporter_Station = 22840,
-  Cave_Teleporter_Station_Ruins = 29310,
-  Cave_Wall_Support = 63840,
-  Ceiling_Lantern = 682,
-  Ceiling_Lantern_Lit = 32476,
-  Ceiling_Light = 8226,
-  Character_Level_Stone = 60762,
-  Chess_Black_Bishop = 16998,
-  Chess_Black_Checker = 16378,
-  Chess_Black_King = 17200,
-  Chess_Black_Knight = 17291,
-  Chess_Black_Pawn = 17282,
-  Chess_Black_Queen = 16204,
-  Chess_Black_Rook = 16142,
-  Chess_Board = 16896,
-  Chess_White_Bishop = 17162,
-  Chess_White_Checker = 16326,
-  Chess_White_King = 16276,
-  Chess_White_Knight = 17038,
-  Chess_White_Pawn = 17240,
-  Chess_White_Queen = 16246,
-  Chess_White_Rook = 17084,
-  Chisel = 44380,
-  ChiselDeck = 37398,
-  Chocolate_Easter_Egg = 30164,
-  Christmas_Gift_Box = 17920,
-  Christmas_Gift_Box_Spawner = 63174,
-  Christmas_Gift_Box_Special = 18144,
-  Christmas_Gift_Mail_Box_01 = 24764,
-  Christmas_Gift_Mail_Box_02 = 16494,
-  Christmas_Gift_Mail_Box_03 = 1080,
-  Christmas_Tree = 56318,
-  Chunk_Directional_Surface = 47534,
-  Chunk_Spherical_Surface = 47614,
-  Coal = 19658,
-  Coal_Ash = 2792,
-  Coal_Boulder_01 = 23502,
-  Coal_Boulder_02 = 57382,
-  Coal_Boulder_03 = 23788,
-  Coal_Training = 51610,
-  Coin_Press = 31306,
-  combat_dummy = 57126,
-  Concoction_Crate = 23304,
-  Constant = 42424,
-  Cooking_Stand = 6742,
-  Copper_Boulder = 65380,
-  Copper_Boulder_Parts = 46024,
-  Copper_Ingot = 32850,
-  Copper_Ore = 2484,
-  Craft_Piece_Side_1Way = 1274,
-  Craft_Piece_Side_2Way = 24046,
-  Craft_Piece_Side_4Way = 32160,
-  Craft_Piece_Side_Flat_1Way = 38606,
-  Craft_Piece_SideFlat_2Way = 26748,
-  Crafting_Deck = 28396,
-  Crane_Center_Piece = 25456,
-  Crank = 15392,
-  Crate = 36180,
-  Cross_Slash = 38008,
-  Crystal_Blue = 38178,
-  Crystal_Blue_NoLight = 14778,
-  Crystal_Cluster_Blue = 18096,
-  Crystal_Gem_Blue = 8002,
-  Crystal_Lance_Blue = 23400,
-  Crystal_Pick_Blue = 2924,
-  Crystal_Shard_Blue = 7092,
-  Crystal_Spit = 37926,
-  Crystal_Structure_Blue = 51128,
-  Crystal_Structure_Rocks = 34144,
-  Crystal_Sword_Blue = 56894,
-  Crystal_Wyrm = 37392,
-  Curled_Wooden_Handle = 64172,
-  Customization_Controller = 5526,
-  Dagger_Blade_Curved = 9704,
-  Dagger_Blade_Edgy = 49402,
-  Dagger_Blade_Round = 56720,
-  Dagger_Blade_Wide = 54482,
-  Dais_Meat_Full_Burnt = 41870,
-  Dais_Meat_Full_Cooked = 43452,
-  Dais_Meat_Full_Ripe = 47394,
-  Dais_Meat_Half_Burnt = 43674,
-  Dais_Meat_Half_Cooked = 43502,
-  Dais_Meat_Half_Ripe = 43294,
-  Darksteel_Ingot = 57556,
-  DebugNet = 12632,
-  DebugTool = 16078,
-  Decrafting_Deck = 62244,
-  Default_Burnt_Stew = 20108,
-  Default_Cooked_Stew = 19398,
-  Default_Raw_Stew = 43078,
-  Digging_Dirt_Mound = 43924,
-  Digging_Dirt_Parts = 2538,
-  Directional_Encounter = 23796,
-  Discovery_Landmark = 37940,
-  Disk_Encounter = 65062,
-  Dried_Grass_Bush = 24480,
-  Dummy_Shelf_Short = 62404,
-  Duplicate_Paper_Variant = 11048,
-  Dynamite = 31326,
-  Easter_Egg_01 = 55462,
-  Easter_Egg_02 = 57998,
-  Easter_Egg_03 = 20128,
-  Easter_Egg_04 = 21558,
-  Edge_Blade_Long_Curve = 17478,
-  Edge_Curved_Blade = 11938,
-  Edge_Short_Curve_Blade = 20892,
-  Edge_Straight_Blade = 30124,
-  Eggplant_Full_Burnt = 55030,
-  Eggplant_Full_Cooked = 54506,
-  Eggplant_Full_Ripe = 53982,
-  Eggplant_Full_Unripe = 53458,
-  Eggplant_Half_Burnt = 62546,
-  Eggplant_Half_Cooked = 62142,
-  Eggplant_Half_Ripe = 61738,
-  Eggplant_Half_Unripe = 61334,
-  Eggplant_Potato_Recipe_Burnt_Stew = 57688,
-  Eggplant_Potato_Recipe_Cooked_Stew = 57712,
-  Eggplant_Potato_Recipe_Raw_Stew = 57736,
-  Eggplant_Tree = 27004,
-  Eggplant_Tree_Separated = 17770,
-  Empty = 40954,
-  Etheral_Arrow = 52366,
-  Evinon_Steel_Ingot = 32198,
-  Explosion_Boulder = 44162,
-  Explosive_Spike = 50412,
-  Fake_Player_combat_dummy = 45454,
-  Feather_Red_Training = 80,
-  Firebug = 40478,
-  Firework = 40748,
-  Flashlight_Lantern = 23642,
-  Flint = 39484,
-  Flint_Training = 2356,
-  Flower_Blue = 23514,
-  Flower_Red = 61634,
-  FlyCam_Player = 44058,
-  Forge = 11872,
-  Forge_Training = 33628,
-  Friend_Request_Token = 15314,
-  Garlic_Full_Burnt = 52934,
-  Garlic_Full_Cooked = 52530,
-  Garlic_Full_Ripe = 52126,
-  Garlic_Full_Unripe = 49162,
-  Garlic_Half_Burnt = 60930,
-  Garlic_Half_Cooked = 60526,
-  Garlic_Half_Ripe = 60122,
-  Garlic_Half_Unripe = 59718,
-  Garlic_Leaves = 1266,
-  Garlic_Roots = 57564,
-  Gacha_Handle = 34422,
-  Geode_Tier_1 = 59336,
-  Geode_Tier_1_Half_01 = 29678,
-  Geode_Tier_1_Half_02 = 38512,
-  Gift_Mail_Box = 56348,
-  Glowing_Mushroom_Recipe_Burnt_Stew = 47384,
-  Glowing_Mushroom_Recipe_Cooked_Stew = 47362,
-  Glowing_Mushroom_Recipe_Raw_Stew = 44774,
-  Gold_Boulder = 2584,
-  Gold_Boulder_Parts = 47738,
-  Gold_Ingot = 30092,
-  Gold_Ore = 61650,
-  GoldCoin = 61648,
-  Gotera = 9466,
-  Gotera_Dart = 3088,
-  Gotera_Seed_Spray = 31540,
-  Gotera_Seedling_Orb = 59342,
-  Gourd_Canteen = 29032,
-  Grass_Clump = 57872,
-  Gravestone_Parts = 2596,
-  Great_Sword_Blade = 63886,
-  Green_Crystal_cluster_03 = 23836,
-  Guard = 51672,
-  Guard_Fancy = 62140,
-  Guard_Handle = 43186,
-  Guard_Hemisphere = 34428,
-  Guard_Pointy_Ends = 28160,
-  Guard_Round_Ends = 21776,
-  Guard_Straight_Ends = 17348,
-  Hammer = 61660,
-  Hammer_Head = 43146,
-  Hammer_Head_Small = 15476,
-  Hammer_Training = 47018,
-  Hand_Camera = 59806,
-  Handle_Bow = 64410,
-  Handle_Fist = 22988,
-  Handle_Large_Branch = 61098,
-  Handle_Large_Cool = 25290,
-  Handle_Large_Standard = 43252,
-  Handle_Long_Straight = 20300,
-  Handle_Medium_Branch = 61400,
-  Handle_Medium_Cool = 61856,
-  Handle_Medium_Curved = 19316,
-  Handle_Medium_Ridged = 60598,
-  Handle_Medium_Standard = 41438,
-  Handle_Medium_Straight = 19180,
-  Handle_Round_Fist = 3506,
-  Handle_Short = 42230,
-  Handle_Short_C_Curve = 34898,
-  Handle_Short_Cool = 5920,
-  Handle_Short_Pointy_End = 28636,
-  Handle_Short_S_Curve = 27820,
-  Handle_Short_Taper = 24198,
-  Handle_Spear = 20640,
-  Handle_Tonfa = 57838,
-  Handy_Cam = 13790,
-  Hard_Metal_Small_Bits = 62594,
-  Hard_Plate_Metal_Medium_Square = 50988,
-  Heart_Receptacle = 56090,
-  Hebios_Camp_Barren = 56012,
-  Hebios_Camp_Spawner = 43300,
-  Hebios_Camp_Valley = 42062,
-  Hebios_Camp_Valley_Center_Section_NEW = 5350,
-  Hebios_Camp_Valley_Center_Section_Pond = 54680,
-  Hebios_Camp_Valley_Front_Section_Spike_Gate = 42358,
-  Hebios_Camp_Valley_Front_Section_Stone_Cliff = 19412,
-  Hebios_Camp_Valley_Left_Section_Archway = 40482,
-  Hebios_Camp_Valley_Left_Section_Hilly_Forest = 37966,
-  Hebios_Closed_Crate_Spawner = 46524,
-  Hebios_Handle_Katana = 53200,
-  Hebios_Handle_Kunai = 18456,
-  Hebios_Handle_Naginata = 24220,
-  Hebios_Handle_Wakizashi = 47662,
-  Hebios_Open_Crate_Spawner = 46522,
-  Hebios_Storage_Chest = 44984,
-  Hitting_Short_Sword_Training = 55646,
-  Hover_Piece = 50934,
-  Iron_Boulder = 45344,
-  Iron_Boulder_Parts = 18070,
-  Iron_Boulder_Training = 10140,
-  Iron_Ingot = 23012,
-  Iron_Ore = 61652,
-  Ka_Karimata_Arrow = 960,
-  Katana = 34994,
-  Key_Standard = 39744,
-  Kunai = 32002,
-  Ladder = 56168,
-  Lantern = 41760,
-  Large_Cave_Mushroom = 29690,
-  Large_Cave_Mushroom_Cluster = 2422,
-  Large_Cave_Mushroom_OLD = 36866,
-  Large_Guard_Rectangle = 9304,
-  Large_Guard_TShape = 23552,
-  Large_Guard_Wedge = 39010,
-  Large_Longsword_Blade = 56124,
-  Large_Mythril_Boulder = 53902,
-  Large_Spiked_Wooden_Club = 55914,
-  Large_Sword = 8374,
-  Leaderboard = 44390,
-  Lectern = 59986,
-  Lectern_Flat = 45828,
-  Leveling_Dummy = 44224,
-  Lever = 27966,
-  Liquid_Pump = 39174,
-  Lockbox = 6974,
-  Lockbox_Docks = 2226,
-  Log_Mallet = 42518,
-  Log_Mallet_v02 = 42030,
-  Logic_Context = 34630,
-  Logic_Operator = 13390,
-  Long_S_Hook = 20598,
-  Loot_Module = 29544,
-  Mail_Deposit_Box = 64204,
-  Main_Menu_Controller = 58810,
-  Map_Board = 60974,
-  Metal_Bow = 25100,
-  Metal_Hammer_Head = 22876,
-  Metal_Tap = 17334,
-  Metal_Wall_Hook = 61180,
-  Mining_Base_Generator = 6714,
-  Modular_Backpack = 12060,
-  Modular_Hook = 60188,
-  Modular_Sack = 8344,
-  Mould = 14826,
-  Mould_Rack = 4070,
-  Mould_Restriction_Zone = 4900,
-  MRK_Fuel_Core = 65358,
-  MRK_Molten_Core = 51764,
-  MRK_Heart_Receptacle_01 = 9566,
-  Mushroom_Mix_Recipe_Burnt_Stew = 27398,
-  Mushroom_Mix_Recipe_Cooked_Stew = 27376,
-  Mushroom_Mix_Recipe_Raw_Stew = 14914,
-  Mushroom_Poultry_Recipe_Burnt_Stew = 54614,
-  Mushroom_Poultry_Recipe_Cooked_Stew = 55358,
-  Mushroom_Poultry_Recipe_Raw_Stew = 55978,
-  Mushroom_Recipe_Burnt_Stew = 30560,
-  Mushroom_Recipe_Cooked_Stew = 31606,
-  Mushroom_Recipe_Raw_Stew = 32650,
-  MushroomBrown_Full_Burnt = 47126,
-  MushroomBrown_Full_Cooked = 46510,
-  MushroomBrown_Full_Ripe = 61666,
-  MushroomBrown_Half_Burnt = 53372,
-  MushroomBrown_Half_Cooked = 50916,
-  MushroomBrown_Half_Ripe = 48460,
-  MushroomCaveLarge_Half_Burnt = 60330,
-  MushroomCaveLarge_Half_Cooked = 9414,
-  MushroomCaveLarge_Half_Ripe = 54182,
-  MushroomCaveSmall_Full_Burnt = 29148,
-  MushroomCaveSmall_Full_Cooked = 40066,
-  MushroomCaveSmall_Full_Ripe = 58270,
-  MushroomCaveSmall_Half_Burnt = 47142,
-  MushroomCaveSmall_Half_Cooked = 44488,
-  MushroomCaveSmall_Half_Ripe = 41834,
-  MushroomGlowing_Full_Burnt = 43856,
-  MushroomGlowing_Full_Cooked = 41428,
-  MushroomGlowing_Full_Ripe = 38966,
-  MushroomGlowing_Half_Burnt = 36504,
-  MushroomGlowing_Half_Cooked = 34042,
-  MushroomGlowing_Half_Ripe = 31580,
-  MushroomRed_Full_Burnt = 46660,
-  MushroomRed_Full_Cooked = 46888,
-  MushroomRed_Full_Ripe = 61658,
-  MushroomRed_Half_Burnt = 43272,
-  MushroomRed_Half_Cooked = 40816,
-  MushroomRed_Half_Ripe = 38360,
-  Mythril_Boulder = 27368,
-  Mythril_Boulder_Parts = 43522,
-  Mythril_Ingot = 24774,
-  Mythril_Ore = 11702,
-  Naginata = 41052,
-  Name_Proxy = 15340,
-  Nand = 42426,
-  Navigation_wheel = 20416,
-  Non_Recipe_Burnt_Stew = 48634,
-  Non_Recipe_Cooked_Stew = 49314,
-  Non_Recipe_Raw_Stew = 49962,
-  Nor = 42420,
-  Not = 42414,
-  Oak_Tree_Seed = 17302,
-  Onion_Full_Burnt = 48718,
-  Onion_Full_Cooked = 48214,
-  Onion_Full_Ripe = 47730,
-  Onion_Full_Unripe = 43966,
-  Onion_Half_Burnt = 59314,
-  Onion_Half_Cooked = 58910,
-  Onion_Half_Ripe = 58506,
-  Onion_Half_Unripe = 58102,
-  Onion_Leaves = 29078,
-  Onion_Roots = 32068,
-  Or = 42416,
-  Orchi_Ingot = 16464,
-  ore_copper = 22768,
-  ore_gold = 38596,
-  ore_iron = 60876,
-  ore_mythril = 18158,
-  ore_silver = 26988,
-  Ore_Storage = 65420,
-  Ore_Training = 56300,
-  Outdoor_Light_Fixture = 4686,
-  Outdoor_Light_Fixture_Dim = 2758,
-  Padlock_Standard = 3830,
-  Page = 40320,
-  Paper = 37066,
-  Phantom = 17772,
-  Phantom_Guard = 6940,
-  Phantom_Head = 43960,
-  Pick_Axe = 61654,
-  Pickaxe_Head = 35878,
-  Pickaxe_Training = 29706,
-  Pink_Crystal_cluster_02 = 15424,
-  Placed_Table = 8520,
-  Placement_Crate = 36614,
-  Player_Template = 61646,
-  Poison_Cloud = 52444,
-  Pole_Hugger_Edgy = 17828,
-  Pole_Hugger_Pointy_Ends = 10962,
-  Pole_Hugger_Short = 4920,
-  Pole_Hugger_Tall = 62282,
-  Pommel = 15658,
-  Pommel_Circle = 57966,
-  Pommel_Cone = 52360,
-  Pommel_Diamond = 42764,
-  Pommel_Large_Square = 42138,
-  Pommel_Squashed = 1736,
-  Pond_Test = 58844,
-  Pond_Water = 23384,
-  Post_Box = 9562,
-  pot_01 = 44028,
-  Potato_Full_Burnt = 1574,
-  Potato_Full_Cooked = 57840,
-  Potato_Full_Ripe = 54692,
-  Potato_Full_Unripe = 52146,
-  Potato_Half_Burnt = 59748,
-  Potato_Half_Cooked = 50612,
-  Potato_Half_Ripe = 48134,
-  Potato_Half_Unripe = 45822,
-  Potato_Puree_Recipe_Burnt_Stew = 57936,
-  Potato_Puree_Recipe_Cooked_Stew = 57960,
-  Potato_Puree_Recipe_Raw_Stew = 57918,
-  Potato_Sapling = 50692,
-  Potion_Medium = 23644,
-  Potion_Small = 62934,
-  Pouch = 38942,
-  Pouch_Training = 57348,
-  Poultry_Onion_Mushroom_Recipe_Burnt_Stew = 57780,
-  Poultry_Onion_Mushroom_Recipe_Cooked_Stew = 57762,
-  Poultry_Onion_Mushroom_Recipe_Raw_Stew = 57804,
-  Poultry_Potato_Recipe_Burnt_Stew = 57894,
-  Poultry_Potato_Recipe_Cooked_Stew = 57852,
-  Poultry_Potato_Recipe_Raw_Stew = 57876,
-  Poultry_Recipe_Burnt_Stew = 10830,
-  Poultry_Recipe_Cooked_Stew = 11448,
-  Poultry_Recipe_Raw_Stew = 12132,
-  Power_Strike_Counter = 37516,
-  Practice_Gate = 64704,
-  Profession_Upgrade_Shrine = 32200,
-  Prongs = 40460,
-  pumpkin_full_burnt = 5532,
-  pumpkin_full_cooked = 5010,
-  pumpkin_full_ripe = 4488,
-  pumpkin_full_unripe = 3966,
-  pumpkin_half_burnt = 3444,
-  pumpkin_half_cooked = 3082,
-  pumpkin_half_ripe = 2720,
-  pumpkin_half_unripe = 2358,
-  pumpkin_piece_burnt = 42218,
-  pumpkin_piece_cooked = 41930,
-  pumpkin_piece_ripe = 41608,
-  pumpkin_piece_unripe = 41286,
-  Pumpkin_Recipe_Burnt_Stew = 62678,
-  Pumpkin_Recipe_Cooked_Stew = 62694,
-  Pumpkin_Recipe_Raw_Stew = 62724,
-  Pumpkin_Tree = 49086,
-  Pumpkin_Tree_Separated = 23566,
-  Quiver = 64640,
-  Random_Placement_Crate = 8246,
-  Random_Spawn_Rectangle = 24644,
-  Rapier_Blade = 11332,
-  Recycler = 60684,
-  Red_Iron_Ingot = 31034,
-  Red_Mushroom_Recipe_Burnt_Stew = 63290,
-  Red_Mushroom_Recipe_Cooked_Stew = 62660,
-  Red_Mushroom_Recipe_Raw_Stew = 62024,
-  Red_Mushroom_Shield = 49188,
-  Red_Sauce_Recipe_Burnt_Stew = 57978,
-  Red_Sauce_Recipe_Cooked_Stew = 58026,
-  Red_Sauce_Recipe_Raw_Stew = 58002,
-  Redwood_Gotera_Core = 41402,
-  Redwood_Tree_Seed = 55054,
-  Repair_Box = 3458,
-  Repair_Box_Standing_Panel = 32704,
-  Repair_Box_Wall_Panel = 41842,
-  Repeater = 40046,
-  Rock_Boulder_01 = 63838,
-  Rock_Boulder_02 = 63828,
-  Rock_Boulder_03 = 63836,
-  Rock_Boulder_04 = 63834,
-  Rock_Cluster = 63824,
-  Rock_Cluster_Tutorial = 25922,
-  Rock_WallBoulder_02 = 63832,
-  Rod_Long = 44066,
-  Rod_Medium = 44204,
-  Rod_Slim_40cm = 59588,
-  Rusty_Axe = 4412,
-  Rusty_Chisel = 40366,
-  Rusty_Greataxe = 29296,
-  Rusty_Greatsword = 63156,
-  Rusty_Hammer = 36126,
-  Rusty_Pickaxe = 46874,
-  Rusty_Pitchfork = 59586,
-  Rusty_Shield = 20684,
-  Rusty_Short_Sword = 44824,
-  Rusty_Spade = 33230,
-  Safe_Point = 33004,
-  Sai = 27038,
-  Salt = 49578,
-  Sandstone_Boulder_01 = 34168,
-  Sandstone_Boulder_02 = 8006,
-  Sandstone_Boulder_03 = 5050,
-  Sandstone_Cluster = 41676,
-  Sandstone_Stone = 55930,
-  ScaleTemp = 64402,
-  Schmeechee_Glowing = 53576,
-  Schmeechee_Orange = 63728,
-  Schmeechee_Poisonous = 31646,
-  Schmeechee_Red = 3532,
-  Scythe_Blade = 26788,
-  Select_Server_Orb = 55760,
-  Send_Post = 53190,
-  Set_Piece = 62334,
-  Shelf = 23630,
-  Shelf_Short = 20452,
-  Shield = 61656,
-  Shield_Core_Bent_Middle = 7232,
-  Shield_Core_Circle_Middle = 52756,
-  Shield_Core_Handle = 4530,
-  Shield_Core_Holed_Middle = 50602,
-  Shield_Part_Half_Circle = 50888,
-  Shield_Part_Half_Circle_Hole = 44704,
-  Shield_Part_Half_Hole = 12416,
-  Shield_Part_Half_Point_01 = 59936,
-  Short_Sword = 38566,
-  Short_Sword_Blade = 55310,
-  Short_Sword_Training = 1150,
-  Shotel_Blade = 36438,
-  Silver_Boulder = 9144,
-  Silver_Boulder_Parts = 17120,
-  Silver_Ingot = 23528,
-  Silver_Ore = 9586,
-  Skill_Orb = 17270,
-  Skill_Orb_Replacer = 23526,
-  Sliding_Door = 33420,
-  Slingshot = 13142,
-  Small_Bone_Spike = 61488,
-  Small_Cave_Mushroom_01 = 33796,
-  Small_Cave_Mushroom_Cluster = 56444,
-  Small_Shield = 63498,
-  Small_Shield_Training = 21312,
-  Smelter = 44646,
-  Soft_Fabric_Large_Roll = 23206,
-  Soft_Fabric_Medium_Roll = 47760,
-  Soft_Fabric_Medium_Strips = 63204,
-  Spawn_Point = 63844,
-  Spawner_Test = 51070,
-  Spear_Head_Pyramid = 13554,
-  Spear_Head_Spiky = 13680,
-  Spear_Head_Standard = 13816,
-  Spectral_Ghost = 57494,
-  Spherical_Encounter = 1222,
-  Spike_Fancy = 12492,
-  Spike_Short = 6934,
-  Spike_Tall = 3558,
-  Spit = 61454,
-  Spriggull = 62050,
-  Spriggull_Egg = 7014,
-  Spriggull_Feather_Blue = 7918,
-  Spriggull_Feather_Green = 25446,
-  Spriggull_Feather_Purple = 36248,
-  Spriggull_Feather_Red = 18734,
-  Spriggull_Fletching_Blue = 50608,
-  Spriggull_Fletching_Red = 24072,
-  Spriggull_Nest = 16680,
-  SpriggullDrumstick_Bone = 24406,
-  SpriggullDrumstick_Full_Burnt = 20570,
-  SpriggullDrumstick_Full_Cooked = 33190,
-  SpriggullDrumstick_Full_Ripe = 43430,
-  SpriggullDrumstick_Half_Burnt = 10908,
-  SpriggullDrumstick_Half_Cooked = 8440,
-  SpriggullDrumstick_Half_Ripe = 5972,
-  SpyGlass = 5170,
-  SpyGlass_Long = 64848,
-  Standard_Side_Pouch_Attachment = 7852,
-  Standard_Side_Tool_Attachment = 59468,
-  Steel_Alloy_Ingot = 22222,
-  Stick = 61674,
-  Stick_Charred = 20564,
-  Stick_Storage = 46252,
-  Stick_Training = 61414,
-  Stone = 61670,
-  Stone_Boulder_01 = 33376,
-  Stone_Boulder_02 = 17686,
-  Stone_Boulder_03 = 12450,
-  Stone_Boulder_Cluster = 8948,
-  Stone_Training = 19490,
-  Storage_Chest = 63826,
-  Storage_Crate_Parts = 16574,
-  Storage_Crate_Redwood_Closed = 59594,
-  Storage_Crate_Redwood_Open = 32788,
-  Street_Post = 57248,
-  Structure_Chest = 35280,
-  Tab_Lever = 3354,
-  Table_Placer = 25418,
-  Tall_Support = 46506,
-  Tall_Support_Beams = 5682,
-  tallPot = 23320,
-  Teleport_Point = 33542,
-  Teleporter_To_Customization = 60372,
-  Temp_Dynamic_Wall = 31628,
-  TEMP_Hebios_Camp_Spawner_Barren = 33858,
-  TEMP_Hebios_Camp_Spawner_Valley = 33880,
-  TEMP_Watch_Tower_Spawner = 44032,
-  Test_Fire = 31268,
-  Test_Serializable_Large = 57330,
-  Test_Serializable_Small = 51498,
-  Thick_Great_Sword_Blade = 25802,
-  timberBlock_1Long = 34586,
-  timberBlock_2Long = 1898,
-  timberBlock_3Long = 1900,
-  Tinder = 34122,
-  Timer_Logic = 18490,
-  Tomato_Full_Burnt = 38742,
-  Tomato_Full_Cooked = 38098,
-  Tomato_Full_Ripe = 37454,
-  Tomato_Full_Unripe = 36810,
-  Tomato_Half_Burnt = 57698,
-  Tomato_Half_Cooked = 57294,
-  Tomato_Half_Ripe = 56890,
-  Tomato_Half_Unripe = 56486,
-  Tomato_Tree = 56492,
-  Tomato_Tree_Separated = 21548,
-  Torch = 56698,
-  Township_Bridge_Broken = 8620,
-  Township_Bridge_Fixed = 33334,
-  Township_Bridge_Repair_Box = 60674,
-  Trade_Deck = 30016,
-  TraderPrototype = 28820,
-  Training_Short_Sword_Blade_COLD = 1850,
-  Training_Short_Sword_Blade_HOT = 13220,
-  Tree = 8860,
-  Tree_Button_Spawner = 3934,
-  Tree_Spawner___Any_Standard = 15738,
-  Tree_Spawner___Small_Standard = 57286,
-  Turabada = 13804,
-  Turabada_Arm = 15584,
-  Turabada_Copper_Destroy_Variant = 34850,
-  Turabada_Copper_Variant = 39056,
-  Turabada_Destroy = 37508,
-  Turabada_Gold_Destroy_Variant = 15310,
-  Turabada_Gold_Variant = 37176,
-  Turabada_Iron_Destroy_Variant = 42690,
-  Turabada_Iron_Variant = 8298,
-  Turabada_Large_Destroy_Variant = 63178,
-  Turabada_Large_Variant = 41172,
-  Turabada_Mythril_Destroy_Variant = 45488,
-  Turabada_Mythril_Variant = 62968,
-  Turabada_Preview = 49464,
-  Turabada_Short_Destroy_Variant = 48002,
-  Turabada_Short_Variant = 63878,
-  Turabada_Silver_Destroy_Variant = 38546,
-  Turabada_Silver_Variant = 45716,
-  Vacuum = 8586,
-  Vegetable_Ragu_Recipe_Burnt_Stew = 58092,
-  Vegetable_Ragu_Recipe_Cooked_Stew = 58074,
-  Vegetable_Ragu_Recipe_Raw_Stew = 58050,
-  Vision_Recipe_Burnt_Stew = 58138,
-  Vision_Recipe_Cooked_Stew = 58120,
-  Vision_Recipe_Raw_Stew = 58162,
-  VR_Player_Character_New = 49582,
-  Wakizashi = 29856,
-  Walk_Air = 50936,
-  Wall_Shelf = 15548,
-  Wall_Street_Post = 50078,
-  Wall_Torch_Holder = 3786,
-  Wallnut_Tree_Seed = 44172,
-  WarHammer = 9630,
-  Water_Well_Dynamic = 14364,
-  Water_Well_Tunnel_Dynamic = 12356,
-  Weapon_Rack_Wall = 13062,
-  Wedge_Training = 53570,
-  White_Gold_Ingot = 13158,
-  Woodcut_B0_B0 = 11470,
-  Woodcut_B0_B0_S15 = 35014,
-  Woodcut_B0_B15_B30 = 35020,
-  Woodcut_B0_E = 29444,
-  Woodcut_B0_S0_S30 = 35028,
-  Woodcut_B15_B15 = 38016,
-  Woodcut_B30_B30 = 62548,
-  Woodcut_B5_B5 = 1780,
-  Woodcut_BranchRoot_V1_B0 = 8158,
-  Woodcut_BranchRoot_V1_B15_S30 = 22660,
-  Woodcut_Leaves_V1_L_F = 42932,
-  Woodcut_Leaves_V1_L_S = 42928,
-  Woodcut_Leaves_V1_S_F = 42934,
-  Woodcut_Leaves_V1_S_S = 42930,
-  Woodcut_Leaves_V2_D = 63786,
-  Woodcut_Leaves_V2_L = 63466,
-  Woodcut_Leaves_V2_Topper = 26276,
-  Woodcut_Root_V1_T0 = 31522,
-  Woodcut_Root_V1_T0_B15 = 34660,
-  Woodcut_Root_V1_T0_S30 = 34546,
-  Woodcut_Root_V1_T30 = 47612,
-  Woodcut_S0_E = 25704,
-  Woodcut_S0_S0 = 44986,
-  Woodcut_S0_S15_S15 = 62106,
-  Woodcut_T0_B0_B30 = 35026,
-  Woodcut_T0_B15_B30 = 21794,
-  Woodcut_T0_E = 49440,
-  Woodcut_T0_T0 = 6554,
-  Woodcut_T0_T0_B30 = 35016,
-  Woodcut_T0_T0_B45 = 52242,
-  Woodcut_T0_T0_S30 = 35022,
-  Woodcut_T0_T0_S30_S30_S30 = 33712,
-  Woodcut_T15_T15 = 40700,
-  Woodcut_T30_T30 = 30226,
-  Woodcut_T5_T5 = 18498,
-  Woodcut_Training_Block = 13392,
-  Woodcut_Twigs_V1__30 = 49360,
-  Woodcut_Twigs_V1_0 = 64824,
-  Woodcut_Twigs_V1_30 = 19674,
-  Woodcut_Twigs_V2__30 = 63554,
-  Woodcut_Twigs_V2_0 = 1846,
-  Woodcut_Twigs_V2_30 = 1452,
-  Woodcut_Twigs_V3__30 = 49972,
-  Woodcut_Twigs_V3_0 = 63168,
-  Woodcut_Twigs_V3_30 = 15084,
-  Woodcut_Twigs_V4_0 = 52628,
-  Woodcut_Twigs_V4_30 = 31554,
-  Woodcut_Wedge = 47118,
-  Woodcut_Wedge_Ash = 232,
-  Woodcut_Wedge_Burnt = 290,
-  Woodcut_Wedge_Charred = 58068,
-  Woodcut_Wedge_Storage = 12512,
-  Woodcutting_Vines_V1_Large = 24682,
-  Woodcutting_Vines_V1_Small_V1 = 24686,
-  Woodcutting_Vines_V1_Small_V2 = 24684,
-  Woodcutting_Vines_V1_Small_V3 = 24688,
-  Wooden_Bag = 30060,
-  Wooden_Barrel = 5890,
-  Wooden_Bowl = 25908,
-  Wooden_Bucket = 63904,
-  Wooden_Dice = 45608,
-  Wooden_Ladle = 15274,
-  Wooden_Short_Sword = 16448,
-  Wooden_Stake = 17262,
-  Wooden_Stirring_Spoon = 23950,
-  woodenPlatform_1x1 = 50942,
-  woodenPlatform_1x1_Torch = 64260,
-  woodenPlatform_1x2 = 50950,
-  woodenPlatform_Railings_1x1 = 50946,
-  woodenPlatform_Stairs_02 = 50940,
-  woodenPlatform_T2x1 = 50944,
-  woodenPlatform_T2x1_1 = 50930,
-  woodenPlatform_W2x2 = 50932,
-  woodenPlatform_W2x3 = 10176,
-  woodenPlatform_W2x4 = 33664,
-  Wyrm = 21642,
-  Wyrm_Arm = 46340,
-  Xnor = 42418,
-  Xor = 42428
-}
diff --git a/src/SpeciesHash.ts b/src/SpeciesHash.ts
deleted file mode 100644
index 07d665e..0000000
--- a/src/SpeciesHash.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export enum SpeciesHash {
-  Oak = 11232
-}
diff --git a/src/components/BasicDecayComponent.test.ts b/src/components/BasicDecayComponent.test.ts
new file mode 100644
index 0000000..7bc1c4f
--- /dev/null
+++ b/src/components/BasicDecayComponent.test.ts
@@ -0,0 +1,131 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { BasicDecayComponent } from './BasicDecayComponent.js';
+
+const componentHash = ComponentHash.BasicDecay;
+const componentName = 'BasicDecay';
+const componentVersion = 3;
+const componentProps = {
+  isDisabled: false,
+  timelineEntry: 133742069
+};
+
+describe('new BasicDecayComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the BasicDecayComponent class', () => {
+      const component = new BasicDecayComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(BasicDecayComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the BasicDecayComponent class', () => {
+      const component = new BasicDecayComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(BasicDecayComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.isDisabled).toStrictEqual(componentProps.isDisabled);
+      expect(component.timelineEntry).toStrictEqual(componentProps.timelineEntry);
+    });
+  });
+});
+
+describe('BasicDecayComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      BasicDecay: new BasicDecayComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // BasicDecayComponent hash.
+    reader.readUnsignedInteger(); // BasicDecayComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the BasicDecayComponent class', () => {
+    const component = BasicDecayComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(BasicDecayComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.isDisabled).toStrictEqual(componentProps.isDisabled);
+    expect(component.timelineEntry).toStrictEqual(componentProps.timelineEntry);
+  });
+});
+
+describe('BasicDecayComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new BasicDecayComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00000011111111000101111011111010100000000000000000000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('BasicDecayComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new BasicDecayComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '111000101001001010010011010100100000000000000000000000000100000100000011111111000101111011111010100000000000000000000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // BasicDecayComponent data length.
+    const isDisabled = reader.readBoolean();
+    const timelineEntry = reader.readUnsignedLong();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(isDisabled).toStrictEqual(componentProps.isDisabled);
+    expect(timelineEntry).toStrictEqual(componentProps.timelineEntry);
+  });
+});
diff --git a/src/components/BasicDecayComponent.ts b/src/components/BasicDecayComponent.ts
new file mode 100644
index 0000000..f3a65d5
--- /dev/null
+++ b/src/components/BasicDecayComponent.ts
@@ -0,0 +1,122 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type BasicDecayComponentPropsV3 = {
+  isDisabled?: boolean | undefined;
+  timelineEntry?: number | undefined;
+};
+
+export type BasicDecayComponentProps = BasicDecayComponentPropsV3;
+
+const HUNDRED_YEARS_TICKS = 31557600000000000;
+
+/**
+ * @see [Class: `BasicDecayComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BasicDecayComponent.md)
+ * @since v3.0.0
+ * @version 3
+ *
+ * @example
+ * import { BasicDecayComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 3;
+ * const component = new BasicDecayComponent({ version: componentVersion });
+ */
+export class BasicDecayComponent extends Component {
+  /**
+   * @since v3
+   *
+   * @example
+   * import { BasicDecayComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 3;
+   * const component = new BasicDecayComponent({ version: componentVersion });
+   *
+   * const isDisabled = component.isDisabled;
+   * // `isDisabled` is `true`
+   */
+  isDisabled: boolean;
+
+  /**
+   * @since v3
+   *
+   * @example
+   * import { BasicDecayComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 3;
+   * const component = new BasicDecayComponent({ version: componentVersion });
+   *
+   * const timelineEntry = component.timelineEntry;
+   * // `timelineEntry` is `31557600000000000`
+   */
+  timelineEntry: number;
+
+  /**
+   * @see [Class: `BasicDecayComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BasicDecayComponent.md)
+   * @since v3.0.0
+   * @version 3
+   *
+   * @example
+   * import { BasicDecayComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 3;
+   * const component = new BasicDecayComponent({ version: componentVersion });
+   */
+  constructor({ version, isDisabled, timelineEntry }: ComponentProps & BasicDecayComponentProps) {
+    const hash = ComponentHash.BasicDecay;
+    const name = 'BasicDecay';
+
+    super({ hash, name, version });
+
+    this.isDisabled = isDisabled ?? true;
+    this.timelineEntry = timelineEntry ?? HUNDRED_YEARS_TICKS;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): BasicDecayComponent {
+    const props: ComponentProps & BasicDecayComponentProps = { version };
+
+    /**
+     * @property {boolean} isDisabled
+     * @since v3
+     */
+    if (props.version >= 3) {
+      props.isDisabled = reader.readBoolean();
+    }
+
+    /**
+     * @property {number} timelineEntry
+     * @since v3
+     */
+    if (props.version >= 3) {
+      props.timelineEntry = reader.readUnsignedLong();
+    }
+
+    return new BasicDecayComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} isDisabled
+     * @since v3
+     */
+    if (version >= 3) {
+      writer.writeBoolean(this.isDisabled);
+    }
+
+    /**
+     * @property {number} timelineEntry
+     * @since v3
+     */
+    if (version >= 3) {
+      writer.writeUnsignedLong(this.timelineEntry);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/Component.test.ts b/src/components/Component.test.ts
new file mode 100644
index 0000000..2d9a842
--- /dev/null
+++ b/src/components/Component.test.ts
@@ -0,0 +1,120 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+
+import { Component } from './Component.js';
+
+describe('new Component()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the Component class', () => {
+      const componentHash = 1337;
+      const componentName = 'topkek';
+      const componentVersion = 1;
+
+      const component = new Component({
+        hash: componentHash,
+        name: componentName,
+        version: componentVersion
+      });
+
+      expect(component).toBeInstanceOf(Component);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+});
+
+describe('Component.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+  const prefab = new Prefab('Grass_Clump');
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // Component hash.
+    reader.readUnsignedInteger(); // Component data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('throws an error', () => {
+    const componentHash = 1337;
+    const componentName = 'topkek';
+    const componentVersion = 1;
+    const expectedToThrow = () => {
+      return Component.fromBinary(fastForwardedReader, componentVersion, componentHash, componentName, 1337);
+    };
+    const expectedError = new Error(
+      'Cannot instantiate base Component class from binary string data. You must call the fromBinary() method on the derived Component class.'
+    );
+
+    expect(expectedToThrow).toThrowError(expectedError);
+  });
+});
+
+describe('Component.toBinary()', () => {
+  it('throws an error', () => {
+    const componentHash = 1337;
+    const componentName = 'topkek';
+    const componentVersion = 1;
+
+    const component = new Component({
+      hash: componentHash,
+      name: componentName,
+      version: componentVersion
+    });
+
+    const expectedToThrow = () => component.toBinary();
+    const expectedError = new Error(
+      'Cannot encode base Component class. You must call the toBinary() method on the derived Component class.'
+    );
+
+    expect(expectedToThrow).toThrowError(expectedError);
+  });
+});
+
+describe('Component.write()', () => {
+  it('throws an error', () => {
+    const componentHash = 1337;
+    const componentName = 'topkek';
+    const componentVersion = 1;
+
+    const component = new Component({
+      hash: componentHash,
+      name: componentName,
+      version: componentVersion
+    });
+
+    const writer = new BinaryWriter();
+
+    const expectedToThrow = () => component.write(writer);
+    const expectedError = new Error(
+      'Cannot encode base Component class. You must call the toBinary() method on the derived Component class.'
+    );
+
+    expect(expectedToThrow).toThrowError(expectedError);
+  });
+});
diff --git a/src/components/Component.ts b/src/components/Component.ts
new file mode 100644
index 0000000..88a8aa5
--- /dev/null
+++ b/src/components/Component.ts
@@ -0,0 +1,146 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+
+type BaseComponentProps = {
+  hash: number;
+  name: string;
+};
+
+export type ComponentProps = {
+  version: number;
+};
+
+/**
+ * Base class for all components. This class should not be used directly. Use any of its derived
+ * classes instead.
+ *
+ * @see [Class: `Component`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/Component.md)
+ * @see [API Reference Documentation](https://github.com/mdingena/att-string-transcoder/tree/main/docs/README.md)
+ */
+export class Component {
+  /**
+   * The hash of the component.
+   *
+   * @example
+   * import { DerivedComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DerivedComponent({ version: componentVersion });
+   *
+   * const hash = component.hash;
+   */
+  hash: number;
+
+  /**
+   * The name of the component.
+   *
+   * @example
+   * import { DerivedComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DerivedComponent({ version: componentVersion });
+   *
+   * const name = component.name;
+   */
+  name: string;
+
+  /**
+   * The version of the component. This controls the shape of the component data and its
+   * (de)serialisation sequence when reading or writing binary data.
+   *
+   * @example
+   * import { DerivedComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DerivedComponent({ version: componentVersion });
+   *
+   * const version = component.version;
+   * // `version` is `1`
+   */
+  version: number;
+
+  /**
+   * Creates a versioned component. This constructor is used internally. You shouldn't create any
+   * instances of this base class.
+   *
+   * @see [Class: `Component`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/Component.md)
+   * @see [API Reference Documentation](https://github.com/mdingena/att-string-transcoder/tree/main/docs/README.md)
+   */
+  constructor({ hash, name, version }: ComponentProps & BaseComponentProps) {
+    this.hash = hash;
+    this.name = name;
+    this.version = version;
+  }
+
+  /**
+   * Reads the binary string data and returns an instantiated component.
+   *
+   * @example
+   * import { BinaryReader, DerivedComponent } from 'att-string-transcoder';
+   *
+   * const reader = new BinaryReader('...');
+   * const componentVersion = 1;
+   *
+   * const component = DerivedComponent.fromBinary(reader, componentVersion);
+   */
+  static fromBinary(reader: BinaryReader, version: number, hash: number, name: string, dataLength: number): Component;
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  static fromBinary(_reader: BinaryReader, _version: number): Component {
+    throw new Error(
+      'Cannot instantiate base Component class from binary string data. You must call the fromBinary() method on the derived Component class.'
+    );
+  }
+
+  /**
+   * Returns a `BinaryString` representation of the component.
+   *
+   * @example
+   * import { DerivedComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DerivedComponent({ version: componentVersion });
+   *
+   * const binaryString = component.toBinary(componentVersion);
+   */
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  toBinary(_version = this.version): BinaryString {
+    throw new Error(
+      'Cannot encode base Component class. You must call the toBinary() method on the derived Component class.'
+    );
+  }
+
+  /**
+   * Writes a `BinaryString` representation of the component to the given `BinaryWriter`, including
+   * the component hash and data length.
+   *
+   * @example
+   * import { BinaryWriter, DerivedComponent } from 'att-string-transcoder';
+   *
+   * const writer = new BinaryWriter();
+   * const componentVersion = 1;
+   *
+   * const component = new DerivedComponent({ version: componentVersion });
+   *
+   * component.write(writer, componentVersion);
+   */
+  write(writer: BinaryWriter, version = this.version): void {
+    const data = this.toBinary(version);
+
+    /**
+     * @property {number} hash
+     */
+    writer.writeUnsignedInteger(this.hash);
+
+    /**
+     * @property {number} dataLength
+     */
+    writer.writeUnsignedInteger(data.length);
+
+    /**
+     * @property {BinaryString} data
+     */
+    writer.writeBits(data);
+  }
+}
diff --git a/src/components/ComponentVersion.ts b/src/components/ComponentVersion.ts
deleted file mode 100644
index f774a44..0000000
--- a/src/components/ComponentVersion.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-export const ComponentVersion = new Map([
-  [1908922854, 1],
-  [159391088, 1],
-  [3801256786, 3],
-  [272188517, 1],
-  [237360636, 2],
-  [391977879, 2],
-  [277505782, 2],
-  [22446553, 2],
-  [403040752, 2],
-  [2617495528, 1],
-  [2978042925, 1],
-  [2801168996, 2],
-  [2495475500, 2],
-  [1176706580, 2],
-  [1001395212, 2],
-  [1874870249, 2],
-  [3230087383, 1],
-  [2498617949, 1],
-  [1714180166, 2],
-  [3109677933, 2],
-  [1509838052, 1],
-  [320224849, 1],
-  [2272630171, 1],
-  [1217391130, 1],
-  [276353327, 1],
-  [1823429789, 1],
-  [3402094521, 1],
-  [751359624, 1],
-  [3608460219, 1],
-  [1390862571, 1],
-  [1085701614, 1],
-  [3445325106, 1],
-  [2126500253, 1],
-  [2624099526, 1],
-  [1871432223, 1],
-  [3373651539, 1],
-  [654225716, 1],
-  [1454441398, 1],
-  [3704379512, 1],
-  [3257374625, 1],
-  [2262399392, 2],
-  [309083880, 1],
-  [586602603, 1],
-  [1934129787, 1],
-  [3146178080, 1],
-  [661497638, 1],
-  [2293737711, 1],
-  [496827038, 1],
-  [2912807649, 1],
-  [2190886200, 1],
-  [2069630919, 1],
-  [3920618075, 1],
-  [3665939353, 1],
-  [3901697682, 1],
-  [1211178616, 1],
-  [2951515968, 1],
-  [1588536425, 1],
-  [2576456808, 1],
-  [2127962967, 1],
-  [70871065, 1],
-  [1063725326, 1],
-  [3101665521, 1],
-  [2815374842, 1],
-  [4081488368, 1],
-  [3820454400, 4],
-  [1624211074, 1],
-  [7704646, 1],
-  [830106687, 1],
-  [1651678475, 1],
-  [2400796504, 1],
-  [910018632, 2],
-  [4144776006, 3],
-  [566175523, 1],
-  [2975913730, 1],
-  [875684520, 1],
-  [2169673426, 1],
-  [3450348902, 1],
-  [1233775263, 1],
-  [43510150, 2],
-  [1645673210, 2],
-  [3431876266, 1],
-  [4095875831, 1],
-  [2314081177, 1],
-  [2590537994, 2],
-  [2443660852, 1],
-  [967932020, 1],
-  [3171294583, 1],
-  [3751351177, 1],
-  [1257282635, 2],
-  [200292695, 3],
-  [2700376822, 1],
-  [3188272159, 1],
-  [3245685963, 1],
-  [2120963769, 1],
-  [392344172, 1],
-  [1391720462, 2],
-  [2610542999, 1],
-  [1081247904, 1],
-  [2880587164, 1],
-  [2563434699, 1],
-  [2253011220, 1],
-  [2814234626, 1],
-  [1964978567, 1],
-  [1228539097, 1],
-  [2026743731, 1],
-  [3538443740, 1],
-  [634164392, 5],
-  [2759613175, 1],
-  [3642863935, 2],
-  [4134534481, 1],
-  [1931537627, 1],
-  [259381630, 1],
-  [3932346318, 1],
-  [2978388169, 1],
-  [1431397437, 2],
-  [3070493599, 2],
-  [3588929783, 1],
-  [3640332570, 1],
-  [1787084913, 4],
-  [1454955908, 1],
-  [788405183, 1],
-  [2563567105, 2],
-  [766675725, 1],
-  [2882590463, 1],
-  [1499506132, 1],
-  [205333986, 1],
-  [4179293747, 1],
-  [3236280681, 3],
-  [902024186, 1],
-  [2450553269, 1],
-  [2629079826, 1],
-  [963907309, 1],
-  [1753993206, 2],
-  [1923918202, 2],
-  [1776498660, 3],
-  [3638500874, 2],
-  [1098050191, 3],
-  [3084373371, 1],
-  [2833060406, 1],
-  [1587058252, 1],
-  [2592242915, 2],
-  [34507654, 1],
-  [1962842866, 1],
-  [4282337604, 1],
-  [3561515449, 1],
-  [2290978823, 1],
-  [3674519521, 1],
-  [2081565440, 1],
-  [4109360768, 2],
-  [3457519710, 2]
-]);
diff --git a/src/components/DoorComponent.test.ts b/src/components/DoorComponent.test.ts
new file mode 100644
index 0000000..7ef6151
--- /dev/null
+++ b/src/components/DoorComponent.test.ts
@@ -0,0 +1,125 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { DoorComponent } from './DoorComponent.js';
+
+const componentHash = ComponentHash.Door;
+const componentName = 'Door';
+const componentVersion = 1;
+const componentProps = {
+  isOpen: true
+};
+
+describe('new DoorComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the DoorComponent class', () => {
+      const component = new DoorComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(DoorComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the DoorComponent class', () => {
+      const component = new DoorComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(DoorComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.isOpen).toStrictEqual(componentProps.isOpen);
+    });
+  });
+});
+
+describe('DoorComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      Door: new DoorComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // DoorComponent hash.
+    reader.readUnsignedInteger(); // DoorComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the DoorComponent class', () => {
+    const component = DoorComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(DoorComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.isOpen).toStrictEqual(componentProps.isOpen);
+  });
+});
+
+describe('DoorComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new DoorComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '1';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('DoorComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new DoorComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData = '10011100011010001001010011000110000000000000000000000000000000011';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // DoorComponent data length.
+    const isOpen = reader.readBoolean();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(isOpen).toStrictEqual(componentProps.isOpen);
+  });
+});
diff --git a/src/components/DoorComponent.ts b/src/components/DoorComponent.ts
new file mode 100644
index 0000000..ad798b3
--- /dev/null
+++ b/src/components/DoorComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type DoorComponentPropsV1 = {
+  isOpen?: boolean | undefined;
+};
+
+export type DoorComponentProps = DoorComponentPropsV1;
+
+/**
+ * @see [Class: `DoorComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/DoorComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { DoorComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new DoorComponent({ version: componentVersion });
+ */
+export class DoorComponent extends Component {
+  /**
+   * Reveals the open state of this component's prefab.
+   *
+   * @since v1
+   *
+   * @example
+   * import { DoorComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DoorComponent({ version: componentVersion });
+   *
+   * const isOpen = component.isOpen;
+   * // `isOpen` is `false`
+   */
+  isOpen: boolean;
+
+  /**
+   * @see [Class: `DoorComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/DoorComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { DoorComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DoorComponent({ version: componentVersion });
+   */
+  constructor({ version, isOpen }: ComponentProps & DoorComponentProps) {
+    const hash = ComponentHash.Door;
+    const name = 'Door';
+
+    super({ hash, name, version });
+
+    this.isOpen = isOpen ?? false;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): DoorComponent {
+    const props: ComponentProps & DoorComponentProps = { version };
+
+    /**
+     * @property {boolean} isOpen
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isOpen = reader.readBoolean();
+    }
+
+    return new DoorComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} isOpen
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isOpen);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/DurabilityModuleComponent.test.ts b/src/components/DurabilityModuleComponent.test.ts
new file mode 100644
index 0000000..416198a
--- /dev/null
+++ b/src/components/DurabilityModuleComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { DurabilityModuleComponent } from './DurabilityModuleComponent.js';
+
+const componentHash = ComponentHash.DurabilityModule;
+const componentName = 'DurabilityModule';
+const componentVersion = 1;
+const componentProps = {
+  integrity: 0.69
+};
+
+describe('new DurabilityModuleComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the DurabilityModuleComponent class', () => {
+      const component = new DurabilityModuleComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(DurabilityModuleComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the DurabilityModuleComponent class', () => {
+      const component = new DurabilityModuleComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(DurabilityModuleComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.integrity).toBeCloseTo(componentProps.integrity, 2);
+    });
+  });
+});
+
+describe('DurabilityModuleComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      DurabilityModule: new DurabilityModuleComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // DurabilityModuleComponent hash.
+    reader.readUnsignedInteger(); // DurabilityModuleComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the DurabilityModuleComponent class', () => {
+    const component = DurabilityModuleComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(DurabilityModuleComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.integrity).toBeCloseTo(componentProps.integrity, 2);
+  });
+});
+
+describe('DurabilityModuleComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new DurabilityModuleComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('DurabilityModuleComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new DurabilityModuleComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '011011111000101111001010000111110000000000000000000000000010000000111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // DurabilityModuleComponent data length.
+    const integrity = reader.readFloat();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(integrity).toBeCloseTo(componentProps.integrity, 2);
+  });
+});
diff --git a/src/components/DurabilityModuleComponent.ts b/src/components/DurabilityModuleComponent.ts
new file mode 100644
index 0000000..88e458b
--- /dev/null
+++ b/src/components/DurabilityModuleComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type DurabilityModuleComponentPropsV1 = {
+  integrity?: number | undefined;
+};
+
+export type DurabilityModuleComponentProps = DurabilityModuleComponentPropsV1;
+
+/**
+ * @see [Class: `DurabilityModuleComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/DurabilityModuleComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { DurabilityModuleComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new DurabilityModuleComponent({ version: componentVersion });
+ */
+export class DurabilityModuleComponent extends Component {
+  /**
+   * The integrity of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { DurabilityModuleComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DurabilityModuleComponent({ version: componentVersion });
+   *
+   * const integrity = component.integrity;
+   * // `integrity` is `1`
+   */
+  integrity: number;
+
+  /**
+   * @see [Class: `DurabilityModuleComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/DurabilityModuleComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { DurabilityModuleComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new DurabilityModuleComponent({ version: componentVersion });
+   */
+  constructor({ version, integrity }: ComponentProps & DurabilityModuleComponentProps) {
+    const hash = ComponentHash.DurabilityModule;
+    const name = 'DurabilityModule';
+
+    super({ hash, name, version });
+
+    this.integrity = integrity ?? 1;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): DurabilityModuleComponent {
+    const props: ComponentProps & DurabilityModuleComponentProps = { version };
+
+    /**
+     * @property {float} integrity
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.integrity = reader.readFloat();
+    }
+
+    return new DurabilityModuleComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {float} integrity
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.integrity);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/FireComponent.test.ts b/src/components/FireComponent.test.ts
new file mode 100644
index 0000000..90fba3a
--- /dev/null
+++ b/src/components/FireComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { FireComponent } from './FireComponent.js';
+
+const componentHash = ComponentHash.Fire;
+const componentName = 'Fire';
+const componentVersion = 1;
+const componentProps = {
+  fuelConsumptionProgress: 0.69
+};
+
+describe('new FireComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the FireComponent class', () => {
+      const component = new FireComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(FireComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the FireComponent class', () => {
+      const component = new FireComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(FireComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.fuelConsumptionProgress).toBeCloseTo(componentProps.fuelConsumptionProgress, 2);
+    });
+  });
+});
+
+describe('FireComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      Fire: new FireComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // FireComponent hash.
+    reader.readUnsignedInteger(); // FireComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the FireComponent class', () => {
+    const component = FireComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(FireComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.fuelConsumptionProgress).toBeCloseTo(componentProps.fuelConsumptionProgress, 2);
+  });
+});
+
+describe('FireComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new FireComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('FireComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new FireComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '110011100001010110010000010111100000000000000000000000000010000000111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // FireComponent data length.
+    const fuelConsumptionProgress = reader.readFloat();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(fuelConsumptionProgress).toBeCloseTo(componentProps.fuelConsumptionProgress, 2);
+  });
+});
diff --git a/src/components/FireComponent.ts b/src/components/FireComponent.ts
new file mode 100644
index 0000000..af51a00
--- /dev/null
+++ b/src/components/FireComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type FireComponentPropsV1 = {
+  fuelConsumptionProgress?: number | undefined;
+};
+
+export type FireComponentProps = FireComponentPropsV1;
+
+/**
+ * @see [Class: `FireComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/FireComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { FireComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new FireComponent({ version: componentVersion });
+ */
+export class FireComponent extends Component {
+  /**
+   * The progress of the consumption of fuel attached to this component's prefab.
+   *
+   * @since v1
+   *
+   * @example
+   * import { FireComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new FireComponent({ version: componentVersion });
+   *
+   * const fuelConsumptionProgress = component.fuelConsumptionProgress;
+   * // `fuelConsumptionProgress` is `1`
+   */
+  fuelConsumptionProgress: number;
+
+  /**
+   * @see [Class: `FireComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/FireComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { FireComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new FireComponent({ version: componentVersion });
+   */
+  constructor({ version, fuelConsumptionProgress }: ComponentProps & FireComponentProps) {
+    const hash = ComponentHash.Fire;
+    const name = 'Fire';
+
+    super({ hash, name, version });
+
+    this.fuelConsumptionProgress = fuelConsumptionProgress ?? 1;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): FireComponent {
+    const props: ComponentProps & FireComponentProps = { version };
+
+    /**
+     * @property {float} fuelConsumptionProgress
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.fuelConsumptionProgress = reader.readFloat();
+    }
+
+    return new FireComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {float} fuelConsumptionProgress
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.fuelConsumptionProgress);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/FuseComponent.test.ts b/src/components/FuseComponent.test.ts
new file mode 100644
index 0000000..078e72b
--- /dev/null
+++ b/src/components/FuseComponent.test.ts
@@ -0,0 +1,136 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { FuseComponent } from './FuseComponent.js';
+
+const componentHash = ComponentHash.Fuse;
+const componentName = 'Fuse';
+const componentVersion = 1;
+const componentProps = {
+  isFinished: false,
+  isLit: true,
+  currentFuseAmount: 0.69
+};
+
+describe('new FuseComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the FuseComponent class', () => {
+      const component = new FuseComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(FuseComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the FuseComponent class', () => {
+      const component = new FuseComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(FuseComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.isFinished).toStrictEqual(componentProps.isFinished);
+      expect(component.isLit).toStrictEqual(componentProps.isLit);
+      expect(component.currentFuseAmount).toBeCloseTo(componentProps.currentFuseAmount, 2);
+    });
+  });
+});
+
+describe('FuseComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      Fuse: new FuseComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // FuseComponent hash.
+    reader.readUnsignedInteger(); // FuseComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the FuseComponent class', () => {
+    const component = FuseComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(FuseComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.isFinished).toStrictEqual(componentProps.isFinished);
+    expect(component.isLit).toStrictEqual(componentProps.isLit);
+    expect(component.currentFuseAmount).toBeCloseTo(componentProps.currentFuseAmount, 2);
+  });
+});
+
+describe('FuseComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new FuseComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '0100111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('FuseComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new FuseComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '11011010100000011100101110011001000000000000000000000000001000100100111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // FuseComponent data length.
+    const isFinished = reader.readBoolean();
+    const isLit = reader.readBoolean();
+    const currentFuseAmount = reader.readFloat();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(isFinished).toStrictEqual(componentProps.isFinished);
+    expect(isLit).toStrictEqual(componentProps.isLit);
+    expect(currentFuseAmount).toBeCloseTo(componentProps.currentFuseAmount, 2);
+  });
+});
diff --git a/src/components/FuseComponent.ts b/src/components/FuseComponent.ts
new file mode 100644
index 0000000..8f8aa70
--- /dev/null
+++ b/src/components/FuseComponent.ts
@@ -0,0 +1,158 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type FuseComponentPropsV1 = {
+  isFinished?: boolean | undefined;
+  isLit?: boolean | undefined;
+  currentFuseAmount?: number | undefined;
+};
+
+export type FuseComponentProps = FuseComponentPropsV1;
+
+/**
+ * @see [Class: `FuseComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/FuseComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { FuseComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new FuseComponent({ version: componentVersion });
+ */
+export class FuseComponent extends Component {
+  /**
+   * Whether the fuse is finished or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { FuseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new FuseComponent({ version: componentVersion });
+   *
+   * const isFinished = component.isFinished;
+   * // `isFinished` is `false`
+   */
+  isFinished: boolean;
+
+  /**
+   * Whether the fuse is lit or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { FuseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new FuseComponent({ version: componentVersion });
+   *
+   * const isLit = component.isLit;
+   * // `isLit` is `false`
+   */
+  isLit: boolean;
+
+  /**
+   * How much of the fuse is left.
+   *
+   * @since v1
+   *
+   * @example
+   * import { FuseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new FuseComponent({ version: componentVersion });
+   *
+   * const currentFuseAmount = component.currentFuseAmount;
+   * // `currentFuseAmount` is `1`
+   */
+  currentFuseAmount: number;
+
+  /**
+   * @see [Class: `FuseComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/FuseComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { FuseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new FuseComponent({ version: componentVersion });
+   */
+  constructor({ version, isFinished, isLit, currentFuseAmount }: ComponentProps & FuseComponentProps) {
+    const hash = ComponentHash.Fuse;
+    const name = 'Fuse';
+
+    super({ hash, name, version });
+
+    this.isFinished = isFinished ?? false;
+    this.isLit = isLit ?? false;
+    this.currentFuseAmount = currentFuseAmount ?? 1;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): FuseComponent {
+    const props: ComponentProps & FuseComponentProps = { version };
+
+    /**
+     * @property {boolean} isFinished
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isFinished = reader.readBoolean();
+    }
+
+    /**
+     * @property {boolean} isLit
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isLit = reader.readBoolean();
+    }
+
+    /**
+     * @property {float} currentFuseAmount
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.currentFuseAmount = reader.readFloat();
+    }
+
+    return new FuseComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} isFinished
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isFinished);
+    }
+
+    /**
+     * @property {boolean} isLit
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isLit);
+    }
+
+    /**
+     * @property {float} currentFuseAmount
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.currentFuseAmount);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/HeatSourceBaseComponent.test.ts b/src/components/HeatSourceBaseComponent.test.ts
new file mode 100644
index 0000000..78ce28d
--- /dev/null
+++ b/src/components/HeatSourceBaseComponent.test.ts
@@ -0,0 +1,137 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { HeatSourceBaseComponent } from './HeatSourceBaseComponent.js';
+
+const componentHash = ComponentHash.HeatSourceBase;
+const componentName = 'HeatSourceBase';
+const componentVersion = 1;
+const componentProps = {
+  isLit: true,
+  progress: 0.69,
+  time: 133742069
+};
+
+describe('new HeatSourceBaseComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the HeatSourceBaseComponent class', () => {
+      const component = new HeatSourceBaseComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(HeatSourceBaseComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the HeatSourceBaseComponent class', () => {
+      const component = new HeatSourceBaseComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(HeatSourceBaseComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.isLit).toStrictEqual(componentProps.isLit);
+      expect(component.progress).toBeCloseTo(componentProps.progress, 2);
+      expect(component.time).toStrictEqual(componentProps.time);
+    });
+  });
+});
+
+describe('HeatSourceBaseComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      HeatSourceBase: new HeatSourceBaseComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // HeatSourceBaseComponent hash.
+    reader.readUnsignedInteger(); // HeatSourceBaseComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the HeatSourceBaseComponent class', () => {
+    const component = HeatSourceBaseComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(HeatSourceBaseComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.isLit).toStrictEqual(componentProps.isLit);
+    expect(component.progress).toBeCloseTo(componentProps.progress, 2);
+    expect(component.time).toStrictEqual(componentProps.time);
+  });
+});
+
+describe('HeatSourceBaseComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new HeatSourceBaseComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '1001111110011000010100011110101110000011111111000101111011111010100000000000000000000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('HeatSourceBaseComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new HeatSourceBaseComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '11110100111011111101111010000000000000000000000000000000011000011001111110011000010100011110101110000011111111000101111011111010100000000000000000000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // HeatSourceBaseComponent data length.
+    const isLit = reader.readBoolean();
+    const progress = reader.readFloat();
+    const time = reader.readUnsignedLong();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(isLit).toStrictEqual(componentProps.isLit);
+    expect(progress).toBeCloseTo(componentProps.progress, 2);
+    expect(time).toStrictEqual(componentProps.time);
+  });
+});
diff --git a/src/components/HeatSourceBaseComponent.ts b/src/components/HeatSourceBaseComponent.ts
new file mode 100644
index 0000000..976379f
--- /dev/null
+++ b/src/components/HeatSourceBaseComponent.ts
@@ -0,0 +1,157 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type HeatSourceBaseComponentPropsV1 = {
+  isLit?: boolean | undefined;
+  progress?: number | undefined;
+  time?: number | undefined;
+};
+
+export type HeatSourceBaseComponentProps = HeatSourceBaseComponentPropsV1;
+
+const HUNDRED_YEARS_TICKS = 31557600000000000;
+
+/**
+ * @see [Class: `HeatSourceBaseComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/HeatSourceBaseComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { HeatSourceBaseComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new HeatSourceBaseComponent({ version: componentVersion });
+ */
+export class HeatSourceBaseComponent extends Component {
+  /**
+   * Whether this heat source is lit and active or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { HeatSourceBaseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new HeatSourceBaseComponent({ version: componentVersion });
+   *
+   * const isLit = component.isLit;
+   */
+  isLit: boolean;
+
+  /**
+   * Progress of the heat source until extinguishing.
+   *
+   * @since v1
+   *
+   * @example
+   * import { HeatSourceBaseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new HeatSourceBaseComponent({ version: componentVersion });
+   *
+   * const progress = component.progress;
+   * // `progress` is `0`
+   */
+  progress: number;
+
+  /**
+   * @since v1
+   *
+   * @example
+   * import { HeatSourceBaseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new HeatSourceBaseComponent({ version: componentVersion });
+   *
+   * const time = component.time;
+   * // `time` is `31557600000000000`
+   */
+  time: number;
+
+  /**
+   * @see [Class: `HeatSourceBaseComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/HeatSourceBaseComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { HeatSourceBaseComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new HeatSourceBaseComponent({ version: componentVersion });
+   */
+  constructor({ version, isLit, progress, time }: ComponentProps & HeatSourceBaseComponentProps) {
+    const hash = ComponentHash.HeatSourceBase;
+    const name = 'HeatSourceBase';
+
+    super({ hash, name, version });
+
+    this.isLit = isLit ?? true;
+    this.progress = progress ?? 0;
+    this.time = time ?? HUNDRED_YEARS_TICKS;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): HeatSourceBaseComponent {
+    const props: ComponentProps & HeatSourceBaseComponentProps = { version };
+
+    /**
+     * @property {boolean} isLit
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isLit = reader.readBoolean();
+    }
+
+    /**
+     * @property {float} progress
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.progress = reader.readFloat();
+    }
+
+    /**
+     * @property {number} time
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.time = reader.readUnsignedLong();
+    }
+
+    return new HeatSourceBaseComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} isLit
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isLit);
+    }
+
+    /**
+     * @property {float} progress
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.progress);
+    }
+
+    /**
+     * @property {number} time
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedLong(this.time);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LiquidContainerComponent.test.ts b/src/components/LiquidContainerComponent.test.ts
new file mode 100644
index 0000000..1f46a48
--- /dev/null
+++ b/src/components/LiquidContainerComponent.test.ts
@@ -0,0 +1,318 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { PresetHash } from '../types/PresetHash.js';
+
+import { LiquidContainerComponent, type LiquidContainerComponentProps } from './LiquidContainerComponent.js';
+
+const componentHash = ComponentHash.LiquidContainer;
+const componentName = 'LiquidContainer';
+const componentVersion = 1;
+
+const effect = {
+  hash: 420,
+  strengthMultiplier: 69
+};
+
+const customData = {
+  color: { r: 0, g: 111, b: 222, a: 128 },
+  isConsumableThroughSkin: false,
+  visualDataHash: 1337,
+  effects: [effect],
+  foodChunks: [1337, 420, 69]
+};
+
+const componentProps: LiquidContainerComponentProps = {
+  canAddTo: true,
+  canRemoveFrom: true,
+  contentLevel: 42,
+  hasContent: true,
+  isCustom: true,
+  presetHash: 0,
+  customData
+};
+
+beforeEach(() => {
+  customData.effects = [effect];
+  componentProps.customData = customData;
+});
+
+describe('new LiquidContainerComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LiquidContainerComponent class', () => {
+      const component = new LiquidContainerComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LiquidContainerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LiquidContainerComponent class', () => {
+      const component = new LiquidContainerComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LiquidContainerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.canAddTo).toStrictEqual(componentProps.canAddTo);
+      expect(component.canRemoveFrom).toStrictEqual(componentProps.canRemoveFrom);
+      expect(component.contentLevel).toStrictEqual(componentProps.contentLevel);
+      expect(component.hasContent).toStrictEqual(componentProps.hasContent);
+      expect(component.isCustom).toStrictEqual(componentProps.isCustom);
+      expect(component.presetHash).toStrictEqual(componentProps.presetHash);
+      expect(component.customData).toStrictEqual(componentProps.customData);
+    });
+  });
+});
+
+describe('LiquidContainerComponent.fromBinary()', () => {
+  describe('when all component props are given', () => {
+    let fastForwardedReader: BinaryReader;
+
+    const prefab = new Prefab('Grass_Clump', {
+      components: {
+        LiquidContainer: new LiquidContainerComponent({ version: componentVersion, ...componentProps })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // LiquidContainerComponent hash.
+      reader.readUnsignedInteger(); // LiquidContainerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns an instance of the LiquidContainerComponent class', () => {
+      const component = LiquidContainerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(LiquidContainerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.canAddTo).toStrictEqual(componentProps.canAddTo);
+      expect(component.canRemoveFrom).toStrictEqual(componentProps.canRemoveFrom);
+      expect(component.contentLevel).toStrictEqual(componentProps.contentLevel);
+      expect(component.hasContent).toStrictEqual(componentProps.hasContent);
+      expect(component.isCustom).toStrictEqual(componentProps.isCustom);
+      expect(component.presetHash).toStrictEqual(componentProps.presetHash);
+      expect(component.customData).toStrictEqual(componentProps.customData);
+    });
+  });
+
+  describe('when CustomData is null', () => {
+    let fastForwardedReader: BinaryReader;
+
+    beforeEach(() => {
+      componentProps.isCustom = false;
+      componentProps.presetHash = PresetHash.TeleportationPotion;
+      componentProps.customData = null;
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          LiquidContainer: new LiquidContainerComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // LiquidContainerComponent hash.
+      reader.readUnsignedInteger(); // LiquidContainerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.isCustom = true;
+      componentProps.presetHash = 0;
+      componentProps.customData = customData;
+    });
+
+    it('returns an instance of the LiquidContainerComponent class', () => {
+      const component = LiquidContainerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(LiquidContainerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.canAddTo).toStrictEqual(componentProps.canAddTo);
+      expect(component.canRemoveFrom).toStrictEqual(componentProps.canRemoveFrom);
+      expect(component.contentLevel).toStrictEqual(componentProps.contentLevel);
+      expect(component.hasContent).toStrictEqual(componentProps.hasContent);
+      expect(component.isCustom).toStrictEqual(componentProps.isCustom);
+      expect(component.presetHash).toStrictEqual(componentProps.presetHash);
+      expect(component.customData).toStrictEqual(componentProps.customData);
+    });
+  });
+
+  describe('when effect is null', () => {
+    let fastForwardedReader: BinaryReader;
+
+    beforeEach(() => {
+      componentProps.customData = {
+        ...customData,
+        effects: [null, effect]
+      };
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          LiquidContainer: new LiquidContainerComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // LiquidContainerComponent hash.
+      reader.readUnsignedInteger(); // LiquidContainerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.customData = customData;
+    });
+
+    it('returns an instance of the LiquidContainerComponent class', () => {
+      const component = LiquidContainerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(LiquidContainerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.canAddTo).toStrictEqual(componentProps.canAddTo);
+      expect(component.canRemoveFrom).toStrictEqual(componentProps.canRemoveFrom);
+      expect(component.contentLevel).toStrictEqual(componentProps.contentLevel);
+      expect(component.hasContent).toStrictEqual(componentProps.hasContent);
+      expect(component.isCustom).toStrictEqual(componentProps.isCustom);
+      expect(component.presetHash).toStrictEqual(componentProps.presetHash);
+      expect(component.customData).toStrictEqual(componentProps.customData);
+    });
+  });
+});
+
+describe('LiquidContainerComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LiquidContainerComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '11100000000000000000000000001010101100000000000000000000000000000000000000000000000000000000000000000010000101101111000000000000000000100001101011110000000000000000001000011000000000000000000000000000000000000000000000010100111001000000000000000000000000000000010000000000000000000000001101001000100001010001010000000000000000000000000000000000000000000000011000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LiquidContainerComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LiquidContainerComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '111110010001101011110110001100110000000000000000000000011100011111100000000000000000000000001010101100000000000000000000000000000000000000000000000000000000000000000010000101101111000000000000000000100001101011110000000000000000001000011000000000000000000000000000000000000000000000010100111001000000000000000000000000000000010000000000000000000000001101001000100001010001010000000000000000000000000000000000000000000000011000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LiquidContainerComponent data length.
+    const canAddTo = reader.readBoolean();
+    const canRemoveFrom = reader.readBoolean();
+    const contentLevel = reader.readSignedInteger();
+    const hasContent = reader.readBoolean();
+    const isCustom = reader.readBoolean();
+    const presetHash = reader.readUnsignedInteger();
+    const customDataNullBit = reader.readBoolean();
+    const r = reader.readFloat();
+    const g = reader.readFloat();
+    const b = reader.readFloat();
+    const a = reader.readFloat();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(canAddTo).toStrictEqual(componentProps.canAddTo);
+    expect(canRemoveFrom).toStrictEqual(componentProps.canRemoveFrom);
+    expect(contentLevel).toStrictEqual(componentProps.contentLevel);
+    expect(hasContent).toStrictEqual(componentProps.hasContent);
+    expect(isCustom).toStrictEqual(componentProps.isCustom);
+    expect(presetHash).toStrictEqual(componentProps.presetHash);
+    expect(customDataNullBit).toStrictEqual(false);
+    expect(r).toStrictEqual(componentProps.customData?.color.r);
+    expect(g).toStrictEqual(componentProps.customData?.color.g);
+    expect(b).toStrictEqual(componentProps.customData?.color.b);
+    expect(a).toStrictEqual(componentProps.customData?.color.a);
+  });
+});
diff --git a/src/components/LiquidContainerComponent.ts b/src/components/LiquidContainerComponent.ts
new file mode 100644
index 0000000..29137d8
--- /dev/null
+++ b/src/components/LiquidContainerComponent.ts
@@ -0,0 +1,480 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type Color = {
+  r: number;
+  g: number;
+  b: number;
+  a: number;
+};
+
+type Effect = null | {
+  hash: number;
+  strengthMultiplier: number;
+};
+
+type FoodChunk = number;
+
+type CustomData = null | {
+  color: Color;
+  isConsumableThroughSkin: boolean;
+  visualDataHash: number;
+  effects: Effect[];
+  foodChunks: FoodChunk[];
+};
+
+type LiquidContainerComponentPropsV1 = {
+  canAddTo?: boolean | undefined;
+  canRemoveFrom?: boolean | undefined;
+  contentLevel?: number | undefined;
+  hasContent?: boolean | undefined;
+  isCustom?: boolean | undefined;
+  presetHash?: number | undefined;
+  customData?: CustomData | undefined;
+};
+
+export type LiquidContainerComponentProps = LiquidContainerComponentPropsV1;
+
+/**
+ * @see [Class: `LiquidContainerComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LiquidContainerComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LiquidContainerComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LiquidContainerComponent({ version: componentVersion });
+ */
+export class LiquidContainerComponent extends Component {
+  /**
+   * Whether any content can be added to the liquid container or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const canAddTo = component.canAddTo;
+   * // `canAddTo` is `false`
+   */
+  canAddTo: boolean;
+
+  /**
+   * Whether any content can be removed from the liquid container or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const canRemoveFrom = component.canRemoveFrom;
+   * // `canRemoveFrom` is `false`
+   */
+  canRemoveFrom: boolean;
+
+  /**
+   * The amount of content stored inside the liquid container.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const contentLevel = component.contentLevel;
+   * // `contentLevel` is `0`
+   */
+  contentLevel: number;
+
+  /**
+   * Whether any content is stored in the liquid container or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const hasContent = component.hasContent;
+   * // `hasContent` is `false`
+   */
+  hasContent: boolean;
+
+  /**
+   * Whether the content stored in the liquid container is custom or a preset.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const isCustom = component.isCustom;
+   * // `isCustom` is `false`
+   */
+  isCustom: boolean;
+
+  /**
+   * The hash of the preset of the contents stored in the liquid container. Is `0` when no preset is used (uses `CustomData` instead).
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const presetHash = component.presetHash;
+   * // `presetHash` is `0`
+   */
+  presetHash: number;
+
+  /**
+   * The data to use as the customised contents of the liquid container.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   *
+   * const customData = component.customData;
+   * // `customData` is `null`
+   */
+  customData: null | CustomData;
+
+  /**
+   * @see [Class: `LiquidContainerComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LiquidContainerComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LiquidContainerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LiquidContainerComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    canAddTo,
+    canRemoveFrom,
+    contentLevel,
+    customData,
+    hasContent,
+    isCustom,
+    presetHash
+  }: ComponentProps & LiquidContainerComponentProps) {
+    const hash = ComponentHash.LiquidContainer;
+    const name = 'LiquidContainer';
+
+    super({ hash, name, version });
+
+    this.canAddTo = canAddTo ?? false;
+    this.canRemoveFrom = canRemoveFrom ?? false;
+    this.contentLevel = Math.round(contentLevel ?? 0);
+    this.hasContent = hasContent ?? (contentLevel ?? 0) > 0;
+    this.isCustom = isCustom ?? false;
+    this.presetHash = presetHash ?? 0;
+    this.customData = customData ?? null;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LiquidContainerComponent {
+    const props: ComponentProps & LiquidContainerComponentProps = { version };
+
+    /**
+     * @property {boolean} canAddTo
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.canAddTo = reader.readBoolean();
+    }
+
+    /**
+     * @property {boolean} canRemoveFrom
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.canRemoveFrom = reader.readBoolean();
+    }
+
+    /**
+     * @property {number} contentLevel
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.contentLevel = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {boolean} hasContent
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.hasContent = reader.readBoolean();
+    }
+
+    /**
+     * @property {boolean} isCustom
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isCustom = reader.readBoolean();
+    }
+
+    /**
+     * @property {number} presetHash
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.presetHash = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {null | CustomData} customData
+     * @since v1
+     */
+    if (props.version >= 1) {
+      /**
+       * @property {boolean} isNull
+       * @since v1
+       */
+      const isNull = reader.readBoolean();
+
+      if (isNull) {
+        props.customData = null;
+      } else {
+        props.customData = {} as Exclude<CustomData, null>;
+
+        /**
+         * @property {Color} color
+         * @since v1
+         */
+        props.customData.color = {
+          r: reader.readFloat(),
+          g: reader.readFloat(),
+          b: reader.readFloat(),
+          a: reader.readFloat()
+        };
+
+        /**
+         * @property {boolean} isConsumableThroughSkin
+         * @since v1
+         */
+        props.customData.isConsumableThroughSkin = reader.readBoolean();
+
+        /**
+         * @property {number} visualDataHash
+         * @since v1
+         */
+        props.customData.visualDataHash = reader.readUnsignedInteger();
+
+        /**
+         * @property {number} effectsLength
+         * @since v1
+         */
+        const effectsLength = reader.readUnsignedInteger();
+        props.customData.effects = [];
+
+        for (let index = 0; index < effectsLength; ++index) {
+          /**
+           * @property {boolean} isNull
+           * @since v1
+           */
+          const isNull = reader.readBoolean();
+
+          if (isNull) {
+            props.customData.effects.push(null);
+            continue;
+          }
+
+          props.customData.effects.push({
+            /**
+             * @property {number} hash
+             * @since v1
+             */
+            hash: reader.readUnsignedInteger(),
+
+            /**
+             * @property {float} strengthMultiplier
+             * @since v1
+             */
+            strengthMultiplier: reader.readFloat()
+          });
+        }
+
+        /**
+         * @property {number} foodChunksLength
+         * @since v1
+         */
+        const foodChunksLength = reader.readUnsignedInteger();
+        props.customData.foodChunks = [];
+
+        for (let index = 0; index < foodChunksLength; ++index) {
+          /**
+           * @property {number} foodChunkHash
+           * @since v1
+           */
+          props.customData.foodChunks.push(reader.readUnsignedInteger());
+        }
+      }
+    }
+
+    return new LiquidContainerComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} canAddTo
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.canAddTo);
+    }
+
+    /**
+     * @property {boolean} canRemoveFrom
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.canRemoveFrom);
+    }
+
+    /**
+     * @property {number} contentLevel
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeSignedInteger(this.contentLevel);
+    }
+
+    /**
+     * @property {boolean} hasContent
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.hasContent);
+    }
+
+    /**
+     * @property {boolean} isCustom
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isCustom);
+    }
+
+    /**
+     * @property {number} presetHash
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.presetHash);
+    }
+
+    /**
+     * @property {null | CustomData} customData
+     * @since v1
+     */
+    if (version >= 1) {
+      const isNull = this.customData === null;
+
+      /**
+       * @property {boolean} isNull
+       * @since v1
+       */
+      writer.writeBoolean(isNull);
+
+      if (this.customData !== null) {
+        /**
+         * @property {Color} color
+         * @since v1
+         */
+        writer.writeFloat(this.customData.color.r);
+        writer.writeFloat(this.customData.color.g);
+        writer.writeFloat(this.customData.color.b);
+        writer.writeFloat(this.customData.color.a);
+
+        /**
+         * @property {boolean} isConsumableThroughSkin
+         * @since v1
+         */
+        writer.writeBoolean(this.customData.isConsumableThroughSkin);
+
+        /**
+         * @property {number} visualDataHash
+         * @since v1
+         */
+        writer.writeUnsignedInteger(this.customData.visualDataHash);
+
+        /**
+         * @property {number} effectsLength
+         * @since v1
+         */
+        writer.writeUnsignedInteger(this.customData.effects.length);
+
+        for (const effect of this.customData.effects) {
+          const isNull = effect === null;
+
+          /**
+           * @property {boolean} isNull
+           * @since v1
+           */
+          writer.writeBoolean(isNull);
+
+          if (!isNull) {
+            /**
+             * @property {number} hash
+             * @since v1
+             */
+            writer.writeUnsignedInteger(effect.hash);
+
+            /**
+             * @property {float} strengthMultiplier
+             * @since v1
+             */
+            writer.writeFloat(effect.strengthMultiplier);
+          }
+        }
+
+        /**
+         * @property {number} foodChunksLength
+         * @since v1
+         */
+        writer.writeUnsignedInteger(this.customData.foodChunks.length);
+
+        for (const foodChunkHash of this.customData.foodChunks) {
+          /**
+           * @property {number} foodChunkHash
+           * @since v1
+           */
+          writer.writeUnsignedInteger(foodChunkHash);
+        }
+      }
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicBoolReceiverComponent.test.ts b/src/components/LogicBoolReceiverComponent.test.ts
new file mode 100644
index 0000000..e7f76fd
--- /dev/null
+++ b/src/components/LogicBoolReceiverComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicBoolReceiverComponent } from './LogicBoolReceiverComponent.js';
+
+const componentHash = ComponentHash.LogicBoolReceiver;
+const componentName = 'LogicBoolReceiver';
+const componentVersion = 1;
+const componentProps = {
+  sender: 1337
+};
+
+describe('new LogicBoolReceiverComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicBoolReceiverComponent class', () => {
+      const component = new LogicBoolReceiverComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicBoolReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicBoolReceiverComponent class', () => {
+      const component = new LogicBoolReceiverComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicBoolReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.sender).toStrictEqual(componentProps.sender);
+    });
+  });
+});
+
+describe('LogicBoolReceiverComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicBoolReceiver: new LogicBoolReceiverComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicBoolReceiverComponent hash.
+    reader.readUnsignedInteger(); // LogicBoolReceiverComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicBoolReceiverComponent class', () => {
+    const component = LogicBoolReceiverComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicBoolReceiverComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.sender).toStrictEqual(componentProps.sender);
+  });
+});
+
+describe('LogicBoolReceiverComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicBoolReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicBoolReceiverComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicBoolReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '110111111001100100010011100010010000000000000000000000000010000000000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicBoolReceiverComponent data length.
+    const sender = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(sender).toStrictEqual(componentProps.sender);
+  });
+});
diff --git a/src/components/LogicBoolReceiverComponent.ts b/src/components/LogicBoolReceiverComponent.ts
new file mode 100644
index 0000000..da3bf5e
--- /dev/null
+++ b/src/components/LogicBoolReceiverComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicBoolReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+export type LogicBoolReceiverComponentProps = LogicBoolReceiverComponentPropsV1;
+
+/**
+ * @see [Class: `LogicBoolReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicBoolReceiverComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicBoolReceiverComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicBoolReceiverComponent({ version: componentVersion });
+ */
+export class LogicBoolReceiverComponent extends Component {
+  /**
+   * The identifier of the `LogicBoolSender` that is connected to this `LogicBoolReceiver`.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicBoolReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicBoolReceiverComponent({ version: componentVersion });
+   *
+   * const sender = component.sender;
+   * // `sender` is `0`
+   */
+  sender: number;
+
+  /**
+   * @see [Class: `LogicBoolReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicBoolReceiverComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicBoolReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicBoolReceiverComponent({ version: componentVersion });
+   */
+  constructor({ version, sender }: ComponentProps & LogicBoolReceiverComponentProps) {
+    const hash = ComponentHash.LogicBoolReceiver;
+    const name = 'LogicBoolReceiver';
+
+    super({ hash, name, version });
+
+    this.sender = sender ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicBoolReceiverComponent {
+    const props: ComponentProps & LogicBoolReceiverComponentProps = { version };
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.sender = reader.readUnsignedInteger();
+    }
+
+    return new LogicBoolReceiverComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.sender);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicBoolSenderComponent.test.ts b/src/components/LogicBoolSenderComponent.test.ts
new file mode 100644
index 0000000..6f34c17
--- /dev/null
+++ b/src/components/LogicBoolSenderComponent.test.ts
@@ -0,0 +1,142 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicBoolSenderComponent } from './LogicBoolSenderComponent.js';
+
+const componentHash = ComponentHash.LogicBoolSender;
+const componentName = 'LogicBoolSender';
+const componentVersion = 2;
+const componentProps = {
+  updatedValue: 1337,
+  changedExternally: 420,
+  identifier: 69,
+  value: true
+};
+
+describe('new LogicBoolSenderComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicBoolSenderComponent class', () => {
+      const component = new LogicBoolSenderComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicBoolSenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicBoolSenderComponent class', () => {
+      const component = new LogicBoolSenderComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicBoolSenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+      expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+      expect(component.identifier).toStrictEqual(componentProps.identifier);
+      expect(component.value).toStrictEqual(componentProps.value);
+    });
+  });
+});
+
+describe('LogicBoolSenderComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicBoolSender: new LogicBoolSenderComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicBoolSenderComponent hash.
+    reader.readUnsignedInteger(); // LogicBoolSenderComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicBoolSenderComponent class', () => {
+    const component = LogicBoolSenderComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicBoolSenderComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(component.identifier).toStrictEqual(componentProps.identifier);
+    expect(component.value).toStrictEqual(componentProps.value);
+  });
+});
+
+describe('LogicBoolSenderComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicBoolSenderComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '0000000000000000000001010011100100000000000000000000000110100100000000000000000000000000010001011';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicBoolSenderComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicBoolSenderComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '01001010111100001001110001001011000000000000000000000000011000010000000000000000000001010011100100000000000000000000000110100100000000000000000000000000010001011';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicBoolSenderComponent data length.
+    const updatedValue = reader.readUnsignedInteger();
+    const changedExternally = reader.readUnsignedInteger();
+    const identifier = reader.readUnsignedInteger();
+    const value = reader.readBoolean();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(identifier).toStrictEqual(componentProps.identifier);
+    expect(value).toStrictEqual(componentProps.value);
+  });
+});
diff --git a/src/components/LogicBoolSenderComponent.ts b/src/components/LogicBoolSenderComponent.ts
new file mode 100644
index 0000000..86a51bc
--- /dev/null
+++ b/src/components/LogicBoolSenderComponent.ts
@@ -0,0 +1,198 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicBoolSenderComponentPropsV2 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: boolean | undefined;
+};
+
+export type LogicBoolSenderComponentProps = LogicBoolSenderComponentPropsV2;
+
+/**
+ * @see [Class: `LogicBoolSenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicBoolSenderComponent.md)
+ * @since v3.0.0
+ * @version 2
+ *
+ * @example
+ * import { LogicBoolSenderComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 2;
+ * const component = new LogicBoolSenderComponent({ version: componentVersion });
+ */
+export class LogicBoolSenderComponent extends Component {
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicBoolSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicBoolSenderComponent({ version: componentVersion });
+   *
+   * const updatedValue = component.updatedValue;
+   * // `updatedValue` is `3171294583`
+   */
+  updatedValue: number;
+
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicBoolSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicBoolSenderComponent({ version: componentVersion });
+   *
+   * const changedExternally = component.changedExternally;
+   * // `changedExternally` is `32`
+   */
+  changedExternally: number;
+
+  /**
+   * The identifier of this `LogicBoolSender` that a `LogicBoolReceiver` connects to.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicBoolSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicBoolSenderComponent({ version: componentVersion });
+   *
+   * const identifier = component.identifier;
+   * // `identifier` is `0`
+   */
+  identifier: number;
+
+  /**
+   * The output value of this `LogicBoolSender` that a `LogicBoolReceiver` reads as its input.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicBoolSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicBoolSenderComponent({ version: componentVersion });
+   *
+   * const value = component.value;
+   * // `value` is `false`
+   */
+  value: boolean;
+
+  /**
+   * @see [Class: `LogicBoolSenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicBoolSenderComponent.md)
+   * @since v3.0.0
+   * @version 2
+   *
+   * @example
+   * import { LogicBoolSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicBoolSenderComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    updatedValue,
+    changedExternally,
+    identifier,
+    value
+  }: ComponentProps & LogicBoolSenderComponentProps) {
+    const hash = ComponentHash.LogicBoolSender;
+    const name = 'LogicBoolSender';
+
+    super({ hash, name, version });
+
+    this.updatedValue = updatedValue ?? 3171294583;
+    this.changedExternally = changedExternally ?? 32;
+    this.identifier = identifier ?? 0;
+    this.value = value ?? false;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicBoolSenderComponent {
+    const props: ComponentProps & LogicBoolSenderComponentProps = { version };
+
+    /**
+     * @property {number} updatedValue
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.updatedValue = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.changedExternally = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.identifier = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {boolean} value
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.value = reader.readBoolean();
+    }
+
+    return new LogicBoolSenderComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} updatedValue
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.updatedValue);
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.changedExternally);
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.identifier);
+    }
+
+    /**
+     * @property {boolean} value
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeBoolean(this.value);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicFloatReceiverComponent.test.ts b/src/components/LogicFloatReceiverComponent.test.ts
new file mode 100644
index 0000000..db23c4a
--- /dev/null
+++ b/src/components/LogicFloatReceiverComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicFloatReceiverComponent } from './LogicFloatReceiverComponent.js';
+
+const componentHash = ComponentHash.LogicFloatReceiver;
+const componentName = 'LogicFloatReceiver';
+const componentVersion = 1;
+const componentProps = {
+  sender: 1337
+};
+
+describe('new LogicFloatReceiverComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicFloatReceiverComponent class', () => {
+      const component = new LogicFloatReceiverComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicFloatReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicFloatReceiverComponent class', () => {
+      const component = new LogicFloatReceiverComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicFloatReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.sender).toStrictEqual(componentProps.sender);
+    });
+  });
+});
+
+describe('LogicFloatReceiverComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicFloatReceiver: new LogicFloatReceiverComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicFloatReceiverComponent hash.
+    reader.readUnsignedInteger(); // LogicFloatReceiverComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicFloatReceiverComponent class', () => {
+    const component = LogicFloatReceiverComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicFloatReceiverComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.sender).toStrictEqual(componentProps.sender);
+  });
+});
+
+describe('LogicFloatReceiverComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicFloatReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicFloatReceiverComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicFloatReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '101111100000100100101100000111110000000000000000000000000010000000000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicFloatReceiverComponent data length.
+    const sender = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(sender).toStrictEqual(componentProps.sender);
+  });
+});
diff --git a/src/components/LogicFloatReceiverComponent.ts b/src/components/LogicFloatReceiverComponent.ts
new file mode 100644
index 0000000..15fe7b4
--- /dev/null
+++ b/src/components/LogicFloatReceiverComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicFloatReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+export type LogicFloatReceiverComponentProps = LogicFloatReceiverComponentPropsV1;
+
+/**
+ * @see [Class: `LogicFloatReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicFloatReceiverComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicFloatReceiverComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicFloatReceiverComponent({ version: componentVersion });
+ */
+export class LogicFloatReceiverComponent extends Component {
+  /**
+   * The identifier of the `LogicFloatSender` that is connected to this `LogicFloatReceiver`.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicFloatReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatReceiverComponent({ version: componentVersion });
+   *
+   * const sender = component.sender;
+   * // `sender` is `0`
+   */
+  sender: number;
+
+  /**
+   * @see [Class: `LogicFloatReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicFloatReceiverComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicFloatReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatReceiverComponent({ version: componentVersion });
+   */
+  constructor({ version, sender }: ComponentProps & LogicFloatReceiverComponentProps) {
+    const hash = ComponentHash.LogicFloatReceiver;
+    const name = 'LogicFloatReceiver';
+
+    super({ hash, name, version });
+
+    this.sender = sender ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicFloatReceiverComponent {
+    const props: ComponentProps & LogicFloatReceiverComponentProps = { version };
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.sender = reader.readUnsignedInteger();
+    }
+
+    return new LogicFloatReceiverComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.sender);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicFloatSenderComponent.test.ts b/src/components/LogicFloatSenderComponent.test.ts
new file mode 100644
index 0000000..178455b
--- /dev/null
+++ b/src/components/LogicFloatSenderComponent.test.ts
@@ -0,0 +1,142 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicFloatSenderComponent } from './LogicFloatSenderComponent.js';
+
+const componentHash = ComponentHash.LogicFloatSender;
+const componentName = 'LogicFloatSender';
+const componentVersion = 1;
+const componentProps = {
+  updatedValue: 1337,
+  changedExternally: 420,
+  identifier: 69,
+  value: 0.69
+};
+
+describe('new LogicFloatSenderComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicFloatSenderComponent class', () => {
+      const component = new LogicFloatSenderComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicFloatSenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicFloatSenderComponent class', () => {
+      const component = new LogicFloatSenderComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicFloatSenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+      expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+      expect(component.identifier).toStrictEqual(componentProps.identifier);
+      expect(component.value).toBeCloseTo(componentProps.value, 2);
+    });
+  });
+});
+
+describe('LogicFloatSenderComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicFloatSender: new LogicFloatSenderComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicFloatSenderComponent hash.
+    reader.readUnsignedInteger(); // LogicFloatSenderComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicFloatSenderComponent class', () => {
+    const component = LogicFloatSenderComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicFloatSenderComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(component.identifier).toStrictEqual(componentProps.identifier);
+    expect(component.value).toBeCloseTo(componentProps.value, 2);
+  });
+});
+
+describe('LogicFloatSenderComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicFloatSenderComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '00000000000000000000010100111001000000000000000000000001101001000000000000000000000000000100010100111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicFloatSenderComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicFloatSenderComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '011111100110101101010110101110010000000000000000000000001000000000000000000000000000010100111001000000000000000000000001101001000000000000000000000000000100010100111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicFloatSenderComponent data length.
+    const updatedValue = reader.readUnsignedInteger();
+    const changedExternally = reader.readUnsignedInteger();
+    const identifier = reader.readUnsignedInteger();
+    const value = reader.readFloat();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(identifier).toStrictEqual(componentProps.identifier);
+    expect(value).toBeCloseTo(componentProps.value, 2);
+  });
+});
diff --git a/src/components/LogicFloatSenderComponent.ts b/src/components/LogicFloatSenderComponent.ts
new file mode 100644
index 0000000..160f61e
--- /dev/null
+++ b/src/components/LogicFloatSenderComponent.ts
@@ -0,0 +1,198 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicFloatSenderComponentPropsV1 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: number | undefined;
+};
+
+export type LogicFloatSenderComponentProps = LogicFloatSenderComponentPropsV1;
+
+/**
+ * @see [Class: `LogicFloatSenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicFloatSenderComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicFloatSenderComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicFloatSenderComponent({ version: componentVersion });
+ */
+export class LogicFloatSenderComponent extends Component {
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicFloatSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatSenderComponent({ version: componentVersion });
+   *
+   * const updatedValue = component.updatedValue;
+   * // `updatedValue` is `3171294583`
+   */
+  updatedValue: number;
+
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicFloatSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatSenderComponent({ version: componentVersion });
+   *
+   * const changedExternally = component.changedExternally;
+   * // `changedExternally` is `32`
+   */
+  changedExternally: number;
+
+  /**
+   * The identifier of this `LogicFloatSender` that a `LogicFloatReceiver` connects to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicFloatSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatSenderComponent({ version: componentVersion });
+   *
+   * const identifier = component.identifier;
+   * // `identifier` is `0`
+   */
+  identifier: number;
+
+  /**
+   * The output value of this `LogicFloatSender` that a `LogicFloatReceiver` reads as its input.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicFloatSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatSenderComponent({ version: componentVersion });
+   *
+   * const value = component.value;
+   * // `value` is `0`
+   */
+  value: number;
+
+  /**
+   * @see [Class: `LogicFloatSenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicFloatSenderComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicFloatSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicFloatSenderComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    updatedValue,
+    changedExternally,
+    identifier,
+    value
+  }: ComponentProps & LogicFloatSenderComponentProps) {
+    const hash = ComponentHash.LogicFloatSender;
+    const name = 'LogicFloatSender';
+
+    super({ hash, name, version });
+
+    this.updatedValue = updatedValue ?? 3171294583;
+    this.changedExternally = changedExternally ?? 32;
+    this.identifier = identifier ?? 0;
+    this.value = value ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicFloatSenderComponent {
+    const props: ComponentProps & LogicFloatSenderComponentProps = { version };
+
+    /**
+     * @property {number} updatedValue
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.updatedValue = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.changedExternally = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.identifier = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {float} value
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.value = reader.readFloat();
+    }
+
+    return new LogicFloatSenderComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} updatedValue
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.updatedValue);
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.changedExternally);
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.identifier);
+    }
+
+    /**
+     * @property {boolean} value
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.value);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicGateReceiverComponent.test.ts b/src/components/LogicGateReceiverComponent.test.ts
new file mode 100644
index 0000000..f605b69
--- /dev/null
+++ b/src/components/LogicGateReceiverComponent.test.ts
@@ -0,0 +1,143 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { LogicOperator } from '../types/LogicOperator.js';
+
+import { LogicGateReceiverComponent } from './LogicGateReceiverComponent.js';
+
+const componentHash = ComponentHash.LogicGateReceiver;
+const componentName = 'LogicGateReceiver';
+const componentVersion = 2;
+const componentProps = {
+  senders: [69, 420, 1337],
+  operationType: LogicOperator.Xor,
+  isInversedOutputSaved: true
+};
+
+describe('new LogicGateReceiverComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicGateReceiverComponent class', () => {
+      const component = new LogicGateReceiverComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicGateReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicGateReceiverComponent class', () => {
+      const component = new LogicGateReceiverComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicGateReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.senders).toStrictEqual(componentProps.senders);
+      expect(component.operationType).toStrictEqual(componentProps.operationType);
+      expect(component.isInversedOutputSaved).toStrictEqual(componentProps.isInversedOutputSaved);
+    });
+  });
+});
+
+describe('LogicGateReceiverComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicGateReceiver: new LogicGateReceiverComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicGateReceiverComponent hash.
+    reader.readUnsignedInteger(); // LogicGateReceiverComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicGateReceiverComponent class', () => {
+    const component = LogicGateReceiverComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicGateReceiverComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.senders).toStrictEqual(componentProps.senders);
+    expect(component.operationType).toStrictEqual(componentProps.operationType);
+    expect(component.isInversedOutputSaved).toStrictEqual(componentProps.isInversedOutputSaved);
+  });
+});
+
+describe('LogicGateReceiverComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicGateReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '00000000000000000000000000000011000000000000000000000000010001010000000000000000000000011010010000000000000000000000010100111001100000000000000000000000000000101';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicGateReceiverComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicGateReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '010100101111001111111000000011100000000000000000000000001010000100000000000000000000000000000011000000000000000000000000010001010000000000000000000000011010010000000000000000000000010100111001100000000000000000000000000000101';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicGateReceiverComponent data length.
+    reader.readUnsignedInteger(); // Senders array length.
+    const sender1 = reader.readUnsignedInteger();
+    const sender2 = reader.readUnsignedInteger();
+    const sender3 = reader.readUnsignedInteger();
+    const operationType = reader.readSignedInteger();
+    const isInversedOutputSaved = reader.readBoolean();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(sender1).toStrictEqual(componentProps.senders[0]);
+    expect(sender2).toStrictEqual(componentProps.senders[1]);
+    expect(sender3).toStrictEqual(componentProps.senders[2]);
+    expect(operationType).toStrictEqual(componentProps.operationType);
+    expect(isInversedOutputSaved).toStrictEqual(componentProps.isInversedOutputSaved);
+  });
+});
diff --git a/src/components/LogicGateReceiverComponent.ts b/src/components/LogicGateReceiverComponent.ts
new file mode 100644
index 0000000..f8165f0
--- /dev/null
+++ b/src/components/LogicGateReceiverComponent.ts
@@ -0,0 +1,181 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { LogicOperator } from '../types/LogicOperator.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicGateReceiverComponentPropsV2 = {
+  senders?: number[] | undefined;
+  operationType?: LogicOperator | undefined;
+  isInversedOutputSaved?: boolean | undefined;
+};
+
+export type LogicGateReceiverComponentProps = LogicGateReceiverComponentPropsV2;
+
+/**
+ * @see [Class: `LogicGateReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicGateReceiverComponent.md)
+ * @since v3.0.0
+ * @version 2
+ *
+ * @example
+ * import { LogicGateReceiverComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 2;
+ * const component = new LogicGateReceiverComponent({ version: componentVersion });
+ */
+export class LogicGateReceiverComponent extends Component {
+  /**
+   * The identifiers of the `Logic*Sender` components that are connected to this `LogicGateReceiver`.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicGateReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicGateReceiverComponent({ version: componentVersion });
+   *
+   * const senders = component.senders;
+   * // `senders` is `[]`
+   */
+  senders: number[];
+
+  /**
+   * The type of operation to perform on the received inputs.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicGateReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicGateReceiverComponent({ version: componentVersion });
+   *
+   * const operationType = component.operationType;
+   * // `operationType` is `0` (AND)
+   */
+  operationType: LogicOperator;
+
+  /**
+   * Whether to inverse the output of this gate.
+   *
+   * @since v2
+   *
+   * @example
+   * import { LogicGateReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicGateReceiverComponent({ version: componentVersion });
+   *
+   * const isInversedOutputSaved = component.isInversedOutputSaved;
+   * // `isInversedOutputSaved` is `false`
+   */
+  isInversedOutputSaved: boolean;
+
+  /**
+   * @see [Class: `LogicGateReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicGateReceiverComponent.md)
+   * @since v3.0.0
+   * @version 2
+   *
+   * @example
+   * import { LogicGateReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new LogicGateReceiverComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    senders,
+    operationType,
+    isInversedOutputSaved
+  }: ComponentProps & LogicGateReceiverComponentProps) {
+    const hash = ComponentHash.LogicGateReceiver;
+    const name = 'LogicGateReceiver';
+
+    super({ hash, name, version });
+
+    this.senders = senders ?? [];
+    this.operationType = operationType ?? LogicOperator.And;
+    this.isInversedOutputSaved = isInversedOutputSaved ?? false;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicGateReceiverComponent {
+    const props: ComponentProps & LogicGateReceiverComponentProps = { version };
+
+    /**
+     * @property {number[]} senders
+     * @since v2
+     */
+    if (props.version >= 2) {
+      const sendersLength = reader.readUnsignedInteger();
+      props.senders = [];
+
+      for (let sendersIndex = 0; sendersIndex < sendersLength; ++sendersIndex) {
+        /**
+         * @property {number} sender
+         * @since v2
+         */
+        props.senders.push(reader.readUnsignedInteger());
+      }
+    }
+
+    /**
+     * @property {number} operationType
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.operationType = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {number} isInversedOutputSaved
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.isInversedOutputSaved = reader.readBoolean();
+    }
+
+    return new LogicGateReceiverComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number[]} senders
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.senders.length);
+
+      for (const sender of this.senders) {
+        /**
+         * @property {number} sender
+         * @since v2
+         */
+        writer.writeUnsignedInteger(sender);
+      }
+    }
+
+    /**
+     * @property {number} operationType
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.operationType);
+    }
+
+    /**
+     * @property {number} isInversedOutputSaved
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeBoolean(this.isInversedOutputSaved);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicIntReceiverComponent.test.ts b/src/components/LogicIntReceiverComponent.test.ts
new file mode 100644
index 0000000..92af469
--- /dev/null
+++ b/src/components/LogicIntReceiverComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicIntReceiverComponent } from './LogicIntReceiverComponent.js';
+
+const componentHash = ComponentHash.LogicIntReceiver;
+const componentName = 'LogicIntReceiver';
+const componentVersion = 1;
+const componentProps = {
+  sender: 1337
+};
+
+describe('new LogicIntReceiverComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicIntReceiverComponent class', () => {
+      const component = new LogicIntReceiverComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicIntReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicIntReceiverComponent class', () => {
+      const component = new LogicIntReceiverComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicIntReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.sender).toStrictEqual(componentProps.sender);
+    });
+  });
+});
+
+describe('LogicIntReceiverComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicIntReceiver: new LogicIntReceiverComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicIntReceiverComponent hash.
+    reader.readUnsignedInteger(); // LogicIntReceiverComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicIntReceiverComponent class', () => {
+    const component = LogicIntReceiverComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicIntReceiverComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.sender).toStrictEqual(componentProps.sender);
+  });
+});
+
+describe('LogicIntReceiverComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicIntReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicIntReceiverComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicIntReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '010000000111001010001000101000000000000000000000000000000010000000000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicIntReceiverComponent data length.
+    const sender = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(sender).toStrictEqual(componentProps.sender);
+  });
+});
diff --git a/src/components/LogicIntReceiverComponent.ts b/src/components/LogicIntReceiverComponent.ts
new file mode 100644
index 0000000..76c298a
--- /dev/null
+++ b/src/components/LogicIntReceiverComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicIntReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+export type LogicIntReceiverComponentProps = LogicIntReceiverComponentPropsV1;
+
+/**
+ * @see [Class: `LogicIntReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicIntReceiverComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicIntReceiverComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicIntReceiverComponent({ version: componentVersion });
+ */
+export class LogicIntReceiverComponent extends Component {
+  /**
+   * The identifier of the `LogicIntSender` that is connected to this `LogicIntReceiver`.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicIntReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntReceiverComponent({ version: componentVersion });
+   *
+   * const sender = component.sender;
+   * // `sender` is `0`
+   */
+  sender: number;
+
+  /**
+   * @see [Class: `LogicIntReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicIntReceiverComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicIntReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntReceiverComponent({ version: componentVersion });
+   */
+  constructor({ version, sender }: ComponentProps & LogicIntReceiverComponentProps) {
+    const hash = ComponentHash.LogicIntReceiver;
+    const name = 'LogicIntReceiver';
+
+    super({ hash, name, version });
+
+    this.sender = sender ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicIntReceiverComponent {
+    const props: ComponentProps & LogicIntReceiverComponentProps = { version };
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.sender = reader.readUnsignedInteger();
+    }
+
+    return new LogicIntReceiverComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.sender);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicIntSenderComponent.test.ts b/src/components/LogicIntSenderComponent.test.ts
new file mode 100644
index 0000000..d0d3cf8
--- /dev/null
+++ b/src/components/LogicIntSenderComponent.test.ts
@@ -0,0 +1,142 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicIntSenderComponent } from './LogicIntSenderComponent.js';
+
+const componentHash = ComponentHash.LogicIntSender;
+const componentName = 'LogicIntSender';
+const componentVersion = 1;
+const componentProps = {
+  updatedValue: 1337,
+  changedExternally: 420,
+  identifier: 69,
+  value: -420
+};
+
+describe('new LogicIntSenderComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicIntSenderComponent class', () => {
+      const component = new LogicIntSenderComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicIntSenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicIntSenderComponent class', () => {
+      const component = new LogicIntSenderComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicIntSenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+      expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+      expect(component.identifier).toStrictEqual(componentProps.identifier);
+      expect(component.value).toStrictEqual(componentProps.value);
+    });
+  });
+});
+
+describe('LogicIntSenderComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicIntSender: new LogicIntSenderComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicIntSenderComponent hash.
+    reader.readUnsignedInteger(); // LogicIntSenderComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicIntSenderComponent class', () => {
+    const component = LogicIntSenderComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicIntSenderComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(component.identifier).toStrictEqual(componentProps.identifier);
+    expect(component.value).toStrictEqual(componentProps.value);
+  });
+});
+
+describe('LogicIntSenderComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicIntSenderComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '00000000000000000000010100111001000000000000000000000001101001000000000000000000000000000100010101111111111111111111111001011100';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicIntSenderComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicIntSenderComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '101010111011001001000101100111000000000000000000000000001000000000000000000000000000010100111001000000000000000000000001101001000000000000000000000000000100010101111111111111111111111001011100';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicIntSenderComponent data length.
+    const updatedValue = reader.readUnsignedInteger();
+    const changedExternally = reader.readUnsignedInteger();
+    const identifier = reader.readUnsignedInteger();
+    const value = reader.readSignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(identifier).toStrictEqual(componentProps.identifier);
+    expect(value).toStrictEqual(componentProps.value);
+  });
+});
diff --git a/src/components/LogicIntSenderComponent.ts b/src/components/LogicIntSenderComponent.ts
new file mode 100644
index 0000000..76224d0
--- /dev/null
+++ b/src/components/LogicIntSenderComponent.ts
@@ -0,0 +1,198 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicIntSenderComponentPropsV2 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: number | undefined;
+};
+
+export type LogicIntSenderComponentProps = LogicIntSenderComponentPropsV2;
+
+/**
+ * @see [Class: `LogicIntSenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicIntSenderComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicIntSenderComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicIntSenderComponent({ version: componentVersion });
+ */
+export class LogicIntSenderComponent extends Component {
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicIntSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntSenderComponent({ version: componentVersion });
+   *
+   * const updatedValue = component.updatedValue;
+   * // `updatedValue` is `3171294583`
+   */
+  updatedValue: number;
+
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicIntSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntSenderComponent({ version: componentVersion });
+   *
+   * const changedExternally = component.changedExternally;
+   * // `changedExternally` is `32`
+   */
+  changedExternally: number;
+
+  /**
+   * The identifier of this `LogicIntSender` that a `LogicIntReceiver` connects to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicIntSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntSenderComponent({ version: componentVersion });
+   *
+   * const identifier = component.identifier;
+   * // `identifier` is `0`
+   */
+  identifier: number;
+
+  /**
+   * The output value of this `LogicIntSender` that a `LogicIntReceiver` reads as its input.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicIntSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntSenderComponent({ version: componentVersion });
+   *
+   * const value = component.value;
+   * // `value` is `0`
+   */
+  value: number;
+
+  /**
+   * @see [Class: `LogicIntSenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicIntSenderComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicIntSenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicIntSenderComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    updatedValue,
+    changedExternally,
+    identifier,
+    value
+  }: ComponentProps & LogicIntSenderComponentProps) {
+    const hash = ComponentHash.LogicIntSender;
+    const name = 'LogicIntSender';
+
+    super({ hash, name, version });
+
+    this.updatedValue = updatedValue ?? 3171294583;
+    this.changedExternally = changedExternally ?? 32;
+    this.identifier = identifier ?? 0;
+    this.value = value ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicIntSenderComponent {
+    const props: ComponentProps & LogicIntSenderComponentProps = { version };
+
+    /**
+     * @property {number} updatedValue
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.updatedValue = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.changedExternally = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.identifier = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} value
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.value = reader.readSignedInteger();
+    }
+
+    return new LogicIntSenderComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} updatedValue
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.updatedValue);
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.changedExternally);
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.identifier);
+    }
+
+    /**
+     * @property {number} value
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeSignedInteger(this.value);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicVector3ReceiverComponent.test.ts b/src/components/LogicVector3ReceiverComponent.test.ts
new file mode 100644
index 0000000..79fab5a
--- /dev/null
+++ b/src/components/LogicVector3ReceiverComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicVector3ReceiverComponent } from './LogicVector3ReceiverComponent.js';
+
+const componentHash = ComponentHash.LogicVector3Receiver;
+const componentName = 'LogicVector3Receiver';
+const componentVersion = 1;
+const componentProps = {
+  sender: 1337
+};
+
+describe('new LogicVector3ReceiverComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicVector3ReceiverComponent class', () => {
+      const component = new LogicVector3ReceiverComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicVector3ReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicVector3ReceiverComponent class', () => {
+      const component = new LogicVector3ReceiverComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicVector3ReceiverComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.sender).toStrictEqual(componentProps.sender);
+    });
+  });
+});
+
+describe('LogicVector3ReceiverComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicVector3Receiver: new LogicVector3ReceiverComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicVector3ReceiverComponent hash.
+    reader.readUnsignedInteger(); // LogicVector3ReceiverComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicVector3ReceiverComponent class', () => {
+    const component = LogicVector3ReceiverComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicVector3ReceiverComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.sender).toStrictEqual(componentProps.sender);
+  });
+});
+
+describe('LogicVector3ReceiverComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicVector3ReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicVector3ReceiverComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicVector3ReceiverComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '010010010011101000000100110110010000000000000000000000000010000000000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicVector3ReceiverComponent data length.
+    const sender = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(sender).toStrictEqual(componentProps.sender);
+  });
+});
diff --git a/src/components/LogicVector3ReceiverComponent.ts b/src/components/LogicVector3ReceiverComponent.ts
new file mode 100644
index 0000000..10aa42e
--- /dev/null
+++ b/src/components/LogicVector3ReceiverComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type LogicVector3ReceiverComponentPropsV1 = {
+  sender?: number | undefined;
+};
+
+export type LogicVector3ReceiverComponentProps = LogicVector3ReceiverComponentPropsV1;
+
+/**
+ * @see [Class: `LogicVector3ReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicVector3ReceiverComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicVector3ReceiverComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicVector3ReceiverComponent({ version: componentVersion });
+ */
+export class LogicVector3ReceiverComponent extends Component {
+  /**
+   * The identifier of the `LogicVector3Sender` that is connected to this `LogicVector3Receiver`.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicVector3ReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3ReceiverComponent({ version: componentVersion });
+   *
+   * const sender = component.sender;
+   * // `sender` is `0`
+   */
+  sender: number;
+
+  /**
+   * @see [Class: `LogicVector3ReceiverComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicVector3ReceiverComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicVector3ReceiverComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3ReceiverComponent({ version: componentVersion });
+   */
+  constructor({ version, sender }: ComponentProps & LogicVector3ReceiverComponentProps) {
+    const hash = ComponentHash.LogicVector3Receiver;
+    const name = 'LogicVector3Receiver';
+
+    super({ hash, name, version });
+
+    this.sender = sender ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicVector3ReceiverComponent {
+    const props: ComponentProps & LogicVector3ReceiverComponentProps = { version };
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.sender = reader.readUnsignedInteger();
+    }
+
+    return new LogicVector3ReceiverComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} sender
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.sender);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/LogicVector3SenderComponent.test.ts b/src/components/LogicVector3SenderComponent.test.ts
new file mode 100644
index 0000000..c383ce4
--- /dev/null
+++ b/src/components/LogicVector3SenderComponent.test.ts
@@ -0,0 +1,146 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { LogicVector3SenderComponent } from './LogicVector3SenderComponent.js';
+
+const componentHash = ComponentHash.LogicVector3Sender;
+const componentName = 'LogicVector3Sender';
+const componentVersion = 1;
+const componentProps = {
+  updatedValue: 1337,
+  changedExternally: 420,
+  identifier: 69,
+  value: { x: 69, y: 420, z: 1337 }
+};
+
+describe('new LogicVector3SenderComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the LogicVector3SenderComponent class', () => {
+      const component = new LogicVector3SenderComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(LogicVector3SenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the LogicVector3SenderComponent class', () => {
+      const component = new LogicVector3SenderComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(LogicVector3SenderComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+      expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+      expect(component.identifier).toStrictEqual(componentProps.identifier);
+      expect(component.value).toStrictEqual(componentProps.value);
+    });
+  });
+});
+
+describe('LogicVector3SenderComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('MRK_Small_Lever', {
+    components: {
+      LogicVector3Sender: new LogicVector3SenderComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // LogicVector3SenderComponent hash.
+    reader.readUnsignedInteger(); // LogicVector3SenderComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the LogicVector3SenderComponent class', () => {
+    const component = LogicVector3SenderComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(LogicVector3SenderComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(component.changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(component.identifier).toStrictEqual(componentProps.identifier);
+    expect(component.value).toStrictEqual(componentProps.value);
+  });
+});
+
+describe('LogicVector3SenderComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new LogicVector3SenderComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101010000101000101000000000000000000100001111010010000000000000000001000100101001110010000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('LogicVector3SenderComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new LogicVector3SenderComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '0111100011001101101001111011001100000000000000000000000011000000000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101010000101000101000000000000000000100001111010010000000000000000001000100101001110010000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // LogicVector3SenderComponent data length.
+    const updatedValue = reader.readUnsignedInteger();
+    const changedExternally = reader.readUnsignedInteger();
+    const identifier = reader.readUnsignedInteger();
+    const value = {
+      x: reader.readFloat(),
+      y: reader.readFloat(),
+      z: reader.readFloat()
+    };
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(updatedValue).toStrictEqual(componentProps.updatedValue);
+    expect(changedExternally).toStrictEqual(componentProps.changedExternally);
+    expect(identifier).toStrictEqual(componentProps.identifier);
+    expect(value).toStrictEqual(componentProps.value);
+  });
+});
diff --git a/src/components/LogicVector3SenderComponent.ts b/src/components/LogicVector3SenderComponent.ts
new file mode 100644
index 0000000..f10c663
--- /dev/null
+++ b/src/components/LogicVector3SenderComponent.ts
@@ -0,0 +1,206 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type Vector3 = { x: number; y: number; z: number };
+
+type LogicVector3SenderComponentPropsV1 = {
+  updatedValue?: number | undefined;
+  changedExternally?: number | undefined;
+  identifier?: number | undefined;
+  value?: Vector3 | undefined;
+};
+
+export type LogicVector3SenderComponentProps = LogicVector3SenderComponentPropsV1;
+
+/**
+ * @see [Class: `LogicVector3SenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicVector3SenderComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { LogicVector3SenderComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new LogicVector3SenderComponent({ version: componentVersion });
+ */
+export class LogicVector3SenderComponent extends Component {
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicVector3SenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3SenderComponent({ version: componentVersion });
+   *
+   * const updatedValue = component.updatedValue;
+   * // `updatedValue` is `3171294583`
+   */
+  updatedValue: number;
+
+  /**
+   * We're not quite sure what this property does.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicVector3SenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3SenderComponent({ version: componentVersion });
+   *
+   * const changedExternally = component.changedExternally;
+   * // `changedExternally` is `32`
+   */
+  changedExternally: number;
+
+  /**
+   * The identifier of this `LogicVector3Sender` that a `LogicVector3Receiver` connects to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicVector3SenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3SenderComponent({ version: componentVersion });
+   *
+   * const identifier = component.identifier;
+   * // `identifier` is `0`
+   */
+  identifier: number;
+
+  /**
+   * The output value of this `LogicVector3Sender` that a `LogicVector3Receiver` reads as its input.
+   *
+   * @since v1
+   *
+   * @example
+   * import { LogicVector3SenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3SenderComponent({ version: componentVersion });
+   *
+   * const value = component.value;
+   * // `value` is `{ x: 0, y: 0, z: 0 }`
+   */
+  value: Vector3;
+
+  /**
+   * @see [Class: `LogicVector3SenderComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/LogicVector3SenderComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { LogicVector3SenderComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new LogicVector3SenderComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    updatedValue,
+    changedExternally,
+    identifier,
+    value
+  }: ComponentProps & LogicVector3SenderComponentProps) {
+    const hash = ComponentHash.LogicVector3Sender;
+    const name = 'LogicVector3Sender';
+
+    super({ hash, name, version });
+
+    this.updatedValue = updatedValue ?? 3171294583;
+    this.changedExternally = changedExternally ?? 32;
+    this.identifier = identifier ?? 0;
+    this.value = value ?? { x: 0, y: 0, z: 0 };
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): LogicVector3SenderComponent {
+    const props: ComponentProps & LogicVector3SenderComponentProps = { version };
+
+    /**
+     * @property {number} updatedValue
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.updatedValue = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.changedExternally = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.identifier = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {Vector3} value
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.value = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat()
+      };
+    }
+
+    return new LogicVector3SenderComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} updatedValue
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.updatedValue);
+    }
+
+    /**
+     * @property {number} changedExternally
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.changedExternally);
+    }
+
+    /**
+     * @property {number} identifier
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.identifier);
+    }
+
+    /**
+     * @property {Vector3} value
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.value.x);
+      writer.writeFloat(this.value.y);
+      writer.writeFloat(this.value.z);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/NetworkRigidbodyComponent.test.ts b/src/components/NetworkRigidbodyComponent.test.ts
new file mode 100644
index 0000000..a1b53c9
--- /dev/null
+++ b/src/components/NetworkRigidbodyComponent.test.ts
@@ -0,0 +1,169 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { NetworkRigidbodyComponent } from './NetworkRigidbodyComponent.js';
+
+const componentHash = ComponentHash.NetworkRigidbody;
+const componentName = 'NetworkRigidbody';
+const componentVersion = 1;
+const componentProps = {
+  position: { x: 1337, y: 420, z: 69 },
+  rotation: { x: 1337, y: 420, z: 69, w: 1 },
+  isKinematic: true,
+  isServerSleeping: false,
+  velocity: { x: 1337, y: 420, z: 69 },
+  angularVelocity: { x: 1337, y: 420, z: 69 }
+};
+
+describe('new NetworkRigidbodyComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the NetworkRigidbodyComponent class', () => {
+      const component = new NetworkRigidbodyComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(NetworkRigidbodyComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the NetworkRigidbodyComponent class', () => {
+      const component = new NetworkRigidbodyComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(NetworkRigidbodyComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.position).toStrictEqual(componentProps.position);
+      expect(component.rotation).toStrictEqual(componentProps.rotation);
+      expect(component.isKinematic).toStrictEqual(componentProps.isKinematic);
+      expect(component.isServerSleeping).toStrictEqual(componentProps.isServerSleeping);
+      expect(component.velocity).toStrictEqual(componentProps.velocity);
+      expect(component.angularVelocity).toStrictEqual(componentProps.angularVelocity);
+    });
+  });
+});
+
+describe('NetworkRigidbodyComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      NetworkRigidbody: new NetworkRigidbodyComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // NetworkRigidbodyComponent hash.
+    reader.readUnsignedInteger(); // NetworkRigidbodyComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the NetworkRigidbodyComponent class', () => {
+    const component = NetworkRigidbodyComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(NetworkRigidbodyComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.position).toStrictEqual(componentProps.position);
+    expect(component.rotation).toStrictEqual(componentProps.rotation);
+    expect(component.isKinematic).toStrictEqual(componentProps.isKinematic);
+    expect(component.isServerSleeping).toStrictEqual(componentProps.isServerSleeping);
+    expect(component.velocity).toStrictEqual(componentProps.velocity);
+    expect(component.angularVelocity).toStrictEqual(componentProps.angularVelocity);
+  });
+});
+
+describe('NetworkRigidbodyComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new NetworkRigidbodyComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '0100010010100111001000000000000001000011110100100000000000000000010000101000101000000000000000000100010010100111001000000000000001000011110100100000000000000000010000101000101000000000000000000011111110000000000000000000000010010001001010011100100000000000000100001111010010000000000000000001000010100010100000000000000000010001001010011100100000000000000100001111010010000000000000000001000010100010100000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('NetworkRigidbodyComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new NetworkRigidbodyComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '10001000100011011001000000000111000000000000000000000001101000100100010010100111001000000000000001000011110100100000000000000000010000101000101000000000000000000100010010100111001000000000000001000011110100100000000000000000010000101000101000000000000000000011111110000000000000000000000010010001001010011100100000000000000100001111010010000000000000000001000010100010100000000000000000010001001010011100100000000000000100001111010010000000000000000001000010100010100000000000000000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // NetworkRigidbodyComponent data length.
+    const position = {
+      x: reader.readFloat(),
+      y: reader.readFloat(),
+      z: reader.readFloat()
+    };
+    const rotation = {
+      x: reader.readFloat(),
+      y: reader.readFloat(),
+      z: reader.readFloat(),
+      w: reader.readFloat()
+    };
+    const isKinematic = reader.readBoolean();
+    const isServerSleeping = reader.readBoolean();
+    const velocity = {
+      x: reader.readFloat(),
+      y: reader.readFloat(),
+      z: reader.readFloat()
+    };
+    const angularVelocity = {
+      x: reader.readFloat(),
+      y: reader.readFloat(),
+      z: reader.readFloat()
+    };
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(position).toStrictEqual(componentProps.position);
+    expect(rotation).toStrictEqual(componentProps.rotation);
+    expect(isKinematic).toStrictEqual(componentProps.isKinematic);
+    expect(isServerSleeping).toStrictEqual(componentProps.isServerSleeping);
+    expect(velocity).toStrictEqual(componentProps.velocity);
+    expect(angularVelocity).toStrictEqual(componentProps.angularVelocity);
+  });
+});
diff --git a/src/components/NetworkRigidbodyComponent.ts b/src/components/NetworkRigidbodyComponent.ts
new file mode 100644
index 0000000..7a6c067
--- /dev/null
+++ b/src/components/NetworkRigidbodyComponent.ts
@@ -0,0 +1,300 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { AngularVelocity } from '../types/AngularVelocity.js';
+import type { BinaryString } from '../types/BinaryString.js';
+import type { Position } from '../types/Position.js';
+import type { Rotation } from '../types/Rotation.js';
+import type { Velocity } from '../types/Velocity.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type NetworkRigidbodyComponentPropsV1 = {
+  position?: Position | undefined;
+  rotation?: Rotation | undefined;
+  isKinematic?: boolean | undefined;
+  isServerSleeping?: boolean | undefined;
+  velocity?: Velocity | undefined;
+  angularVelocity?: AngularVelocity | undefined;
+};
+
+export type NetworkRigidbodyComponentProps = NetworkRigidbodyComponentPropsV1;
+
+/**
+ * Controls physical behaviour of the `Prefab` it is attached to.
+ *
+ * @see [Class: `NetworkRigidbodyComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/NetworkRigidbodyComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+ */
+export class NetworkRigidbodyComponent extends Component {
+  /**
+   * Position of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   *
+   * const position = component.position;
+   * // `position` is `{ x: 0, y: 0, z: 0 }`
+   */
+  position: Position;
+
+  /**
+   * Rotation of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   *
+   * const rotation = component.rotation;
+   * // `rotation` is `{ x: 0, y: 0, z: 0, w: 1 }`
+   */
+  rotation: Rotation;
+
+  /**
+   * Whether the prefab this component is attached to is [kinematic](https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html) or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   *
+   * const isKinematic = component.isKinematic;
+   * // `isKinematic` is `false`
+   */
+  isKinematic: boolean;
+
+  /**
+   * Whether the prefab this component is attached to is [sleeping](https://docs.unity3d.com/Manual/RigidbodiesOverview.html) or not.
+   *
+   * @since v1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   *
+   * const isServerSleeping = component.isServerSleeping;
+   * // `isServerSleeping` is `false`
+   */
+  isServerSleeping: boolean;
+
+  /**
+   * Velocity of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   *
+   * const velocity = component.velocity;
+   * // `velocity` is `{ x: 0, y: 0, z: 0 }`
+   */
+  velocity: Velocity;
+
+  /**
+   * Angular velocity of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   *
+   * const angularVelocity = component.angularVelocity;
+   * // `angularVelocity` is `{ x: 0, y: 0, z: 0 }`
+   */
+  angularVelocity: AngularVelocity;
+
+  /**
+   * @see [Class: `NetworkRigidbodyComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/NetworkRigidbodyComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { NetworkRigidbodyComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new NetworkRigidbodyComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    position,
+    rotation,
+    isKinematic,
+    isServerSleeping,
+    velocity,
+    angularVelocity
+  }: ComponentProps & NetworkRigidbodyComponentProps) {
+    const hash = ComponentHash.NetworkRigidbody;
+    const name = 'NetworkRigidbody';
+
+    super({ hash, name, version });
+
+    this.position = position ?? { x: 0, y: 0, z: 0 };
+    this.rotation = rotation ?? { x: 0, y: 0, z: 0, w: 1 };
+    this.isKinematic = isKinematic ?? false;
+    this.isServerSleeping = isServerSleeping ?? false;
+    this.velocity = velocity ?? { x: 0, y: 0, z: 0 };
+    this.angularVelocity = angularVelocity ?? { x: 0, y: 0, z: 0 };
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): NetworkRigidbodyComponent {
+    const props: ComponentProps & NetworkRigidbodyComponentProps = { version };
+
+    /**
+     * @property {Position} position
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.position = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat()
+      };
+    }
+
+    /**
+     * @property {Rotation} rotation
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.rotation = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat(),
+        w: reader.readFloat()
+      };
+    }
+
+    /**
+     * @property {boolean} isKinematic
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isKinematic = reader.readBoolean();
+    }
+
+    /**
+     * @property {boolean} isServerSleeping
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isServerSleeping = reader.readBoolean();
+    }
+
+    /**
+     * @property {Velocity} velocity
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.velocity = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat()
+      };
+    }
+
+    /**
+     * @property {AngularVelocity} angularVelocity
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.angularVelocity = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat()
+      };
+    }
+
+    return new NetworkRigidbodyComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {Position} position
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.position.x);
+      writer.writeFloat(this.position.y);
+      writer.writeFloat(this.position.z);
+    }
+
+    /**
+     * @property {Rotation} rotation
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.rotation.x);
+      writer.writeFloat(this.rotation.y);
+      writer.writeFloat(this.rotation.z);
+      writer.writeFloat(this.rotation.w);
+    }
+
+    /**
+     * @property {boolean} isKinematic
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isKinematic);
+    }
+
+    /**
+     * @property {boolean} isServerSleeping
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isServerSleeping);
+    }
+
+    /**
+     * @property {Velocity} velocity
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.velocity.x);
+      writer.writeFloat(this.velocity.y);
+      writer.writeFloat(this.velocity.z);
+    }
+
+    /**
+     * @property {AngularVelocity} angularVelocity
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.angularVelocity.x);
+      writer.writeFloat(this.angularVelocity.y);
+      writer.writeFloat(this.angularVelocity.z);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/PhysicalMaterialPartComponent.test.ts b/src/components/PhysicalMaterialPartComponent.test.ts
new file mode 100644
index 0000000..dbdf3c8
--- /dev/null
+++ b/src/components/PhysicalMaterialPartComponent.test.ts
@@ -0,0 +1,126 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { PhysicalMaterialPartComponent } from './PhysicalMaterialPartComponent.js';
+
+const componentHash = ComponentHash.PhysicalMaterialPart;
+const componentName = 'PhysicalMaterialPart';
+const componentVersion = 1;
+const componentProps = {
+  materialHash: 1337
+};
+
+describe('new PhysicalMaterialPartComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the PhysicalMaterialPartComponent class', () => {
+      const component = new PhysicalMaterialPartComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(PhysicalMaterialPartComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the PhysicalMaterialPartComponent class', () => {
+      const component = new PhysicalMaterialPartComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(PhysicalMaterialPartComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.materialHash).toStrictEqual(componentProps.materialHash);
+    });
+  });
+});
+
+describe('PhysicalMaterialPartComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      PhysicalMaterialPart: new PhysicalMaterialPartComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // PhysicalMaterialPartComponent hash.
+    reader.readUnsignedInteger(); // PhysicalMaterialPartComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the PhysicalMaterialPartComponent class', () => {
+    const component = PhysicalMaterialPartComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(PhysicalMaterialPartComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.materialHash).toStrictEqual(componentProps.materialHash);
+  });
+});
+
+describe('PhysicalMaterialPartComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new PhysicalMaterialPartComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '00000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('PhysicalMaterialPartComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new PhysicalMaterialPartComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '000100000011100101000100011001010000000000000000000000000010000000000000000000000000010100111001';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // PhysicalMaterialPartComponent data length.
+    const materialHash = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(materialHash).toStrictEqual(componentProps.materialHash);
+  });
+});
diff --git a/src/components/PhysicalMaterialPartComponent.ts b/src/components/PhysicalMaterialPartComponent.ts
new file mode 100644
index 0000000..b6f16bd
--- /dev/null
+++ b/src/components/PhysicalMaterialPartComponent.ts
@@ -0,0 +1,93 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { PhysicalMaterialPartHash } from '../types/PhysicalMaterialPartHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type PhysicalMaterialPartComponentPropsV1 = {
+  materialHash?: number | undefined;
+};
+
+export type PhysicalMaterialPartComponentProps = PhysicalMaterialPartComponentPropsV1;
+
+/**
+ * Controls physical appearance of the `Prefab` it is attached to.
+ *
+ * @see [Class: `PhysicalMaterialPartComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/PhysicalMaterialPartComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { PhysicalMaterialPartComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new PhysicalMaterialPartComponent({ version: componentVersion });
+ */
+export class PhysicalMaterialPartComponent extends Component {
+  /**
+   * The hash of the physical material of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { PhysicalMaterialPartComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new PhysicalMaterialPartComponent({ version: componentVersion });
+   *
+   * const materialHash = component.materialHash;
+   * // `materialHash` is `1`
+   */
+  materialHash: number;
+
+  /**
+   * @see [Class: `PhysicalMaterialPartComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/PhysicalMaterialPartComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { PhysicalMaterialPartComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new PhysicalMaterialPartComponent({ version: componentVersion });
+   */
+  constructor({ version, materialHash }: ComponentProps & PhysicalMaterialPartComponentProps) {
+    const hash = ComponentHash.PhysicalMaterialPart;
+    const name = 'PhysicalMaterialPart';
+
+    super({ hash, name, version });
+
+    this.materialHash = materialHash ?? PhysicalMaterialPartHash.Iron;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): PhysicalMaterialPartComponent {
+    const props: ComponentProps & PhysicalMaterialPartComponentProps = { version };
+
+    /**
+     * @property {number} materialHash
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.materialHash = reader.readUnsignedInteger();
+    }
+
+    return new PhysicalMaterialPartComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} materialHash
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.materialHash);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/PickupComponent.test.ts b/src/components/PickupComponent.test.ts
new file mode 100644
index 0000000..9b24fca
--- /dev/null
+++ b/src/components/PickupComponent.test.ts
@@ -0,0 +1,366 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { PickupComponent, type PickupComponentProps } from './PickupComponent.js';
+
+const componentHash = ComponentHash.Pickup;
+const componentName = 'Pickup';
+
+const grabPointParameters = {
+  grabPointIndex: -420,
+  lastLinearPosition: 0.69,
+  lastPosition: {
+    x: 1337,
+    y: 420,
+    z: 69
+  },
+  lastRotation: {
+    x: 1337,
+    y: 420,
+    z: 69,
+    w: 1
+  }
+};
+
+const componentPropsV1 = {
+  lastInteractorPlayerId: 1337
+};
+
+const componentPropsV2 = {
+  lastInteractorPlayerId: 1337,
+  dockedMemory: [grabPointParameters]
+};
+
+describe('new PickupComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the PickupComponent class', () => {
+      const componentVersion = 2;
+      const component = new PickupComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(PickupComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    describe('for version 1', () => {
+      const componentVersion = 1;
+      const componentProps = componentPropsV1;
+
+      it('returns an instance of the PickupComponent class', () => {
+        const component = new PickupComponent({ version: componentVersion, ...componentProps });
+
+        expect(component).toBeInstanceOf(PickupComponent);
+        expect(component.hash).toStrictEqual(componentHash);
+        expect(component.name).toStrictEqual(componentName);
+        expect(component.version).toStrictEqual(componentVersion);
+        expect(component.lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+      });
+    });
+
+    describe('for version 2', () => {
+      const componentVersion = 2;
+      const componentProps = componentPropsV2;
+
+      it('returns an instance of the PickupComponent class', () => {
+        const component = new PickupComponent({ version: componentVersion, ...componentProps });
+
+        expect(component).toBeInstanceOf(PickupComponent);
+        expect(component.hash).toStrictEqual(componentHash);
+        expect(component.name).toStrictEqual(componentName);
+        expect(component.version).toStrictEqual(componentVersion);
+        expect(component.lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+        expect(component.dockedMemory).toStrictEqual(componentProps.dockedMemory);
+      });
+    });
+  });
+});
+
+describe('PickupComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  describe('for version 1', () => {
+    const componentVersion = 1;
+    const componentProps = componentPropsV1;
+
+    const prefab = new Prefab('Grass_Clump', {
+      components: {
+        Pickup: new PickupComponent({ version: componentVersion, ...componentProps })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // PickupComponent hash.
+      reader.readUnsignedInteger(); // PickupComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns an instance of the PickupComponent class', () => {
+      const component = PickupComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(PickupComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+    });
+  });
+
+  describe('for version 2', () => {
+    describe('when all component props are given', () => {
+      const componentVersion = 2;
+      const componentProps = componentPropsV2;
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          Pickup: new PickupComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      beforeEach(() => {
+        const saveString = prefab.toSaveString();
+        const [dataString] = saveString.split('|');
+
+        if (typeof dataString === 'undefined') {
+          throw new Error('Invalid test data.');
+        }
+
+        const unsignedIntegers = dataString.split(',').map(Number);
+
+        const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+        const reader = new BinaryReader(data.toBinaryString());
+
+        reader.readUnsignedInteger(); // Root prefab hash.
+        reader.readUnsignedInteger(); // SaveString bytes.
+        reader.readUnsignedInteger(); // Parent prefab hash.
+        reader.readFloat(); // Parent position X.
+        reader.readFloat(); // Parent position Y.
+        reader.readFloat(); // Parent position Z.
+        reader.readFloat(); // Parent rotation X.
+        reader.readFloat(); // Parent rotation Y.
+        reader.readFloat(); // Parent rotation Z.
+        reader.readFloat(); // Parent rotation W.
+        reader.readFloat(); // Parent scale.
+        reader.readUnsignedInteger(); // PickupComponent hash.
+        reader.readUnsignedInteger(); // PickupComponent data length.
+
+        fastForwardedReader = reader;
+      });
+
+      it('returns an instance of the PickupComponent class', () => {
+        const component = PickupComponent.fromBinary(fastForwardedReader, componentVersion);
+
+        expect(component).toBeInstanceOf(PickupComponent);
+        expect(component.hash).toStrictEqual(componentHash);
+        expect(component.name).toStrictEqual(componentName);
+        expect(component.version).toStrictEqual(componentVersion);
+        expect(component.lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+        expect(component.dockedMemory[0]?.grabPointIndex).toStrictEqual(componentProps.dockedMemory[0]?.grabPointIndex);
+        expect(component.dockedMemory[0]?.lastLinearPosition).toBeCloseTo(
+          componentProps.dockedMemory[0]?.lastLinearPosition ?? 0,
+          2
+        );
+        expect(component.dockedMemory[0]?.lastPosition).toStrictEqual(componentProps.dockedMemory[0]?.lastPosition);
+        expect(component.dockedMemory[0]?.lastRotation).toStrictEqual(componentProps.dockedMemory[0]?.lastRotation);
+      });
+    });
+
+    describe('when GrabPointParameters is null', () => {
+      const componentVersion = 2;
+      let componentProps: PickupComponentProps;
+
+      beforeEach(() => {
+        componentProps = componentPropsV2;
+        componentProps.dockedMemory = [null];
+
+        const prefab = new Prefab('Grass_Clump', {
+          components: {
+            Pickup: new PickupComponent({ version: componentVersion, ...componentProps })
+          }
+        });
+        const saveString = prefab.toSaveString();
+        const [dataString] = saveString.split('|');
+
+        if (typeof dataString === 'undefined') {
+          throw new Error('Invalid test data.');
+        }
+
+        const unsignedIntegers = dataString.split(',').map(Number);
+
+        const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+        const reader = new BinaryReader(data.toBinaryString());
+
+        reader.readUnsignedInteger(); // Root prefab hash.
+        reader.readUnsignedInteger(); // SaveString bytes.
+        reader.readUnsignedInteger(); // Parent prefab hash.
+        reader.readFloat(); // Parent position X.
+        reader.readFloat(); // Parent position Y.
+        reader.readFloat(); // Parent position Z.
+        reader.readFloat(); // Parent rotation X.
+        reader.readFloat(); // Parent rotation Y.
+        reader.readFloat(); // Parent rotation Z.
+        reader.readFloat(); // Parent rotation W.
+        reader.readFloat(); // Parent scale.
+        reader.readUnsignedInteger(); // PickupComponent hash.
+        reader.readUnsignedInteger(); // PickupComponent data length.
+
+        fastForwardedReader = reader;
+      });
+
+      afterEach(() => {
+        componentProps.dockedMemory = [grabPointParameters];
+      });
+
+      it('returns an instance of the PickupComponent class', () => {
+        const component = PickupComponent.fromBinary(fastForwardedReader, componentVersion);
+
+        expect(component).toBeInstanceOf(PickupComponent);
+        expect(component.hash).toStrictEqual(componentHash);
+        expect(component.name).toStrictEqual(componentName);
+        expect(component.version).toStrictEqual(componentVersion);
+        expect(component.lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+        expect(component.dockedMemory).toStrictEqual([null]);
+      });
+    });
+  });
+});
+
+describe('PickupComponent.toBinary()', () => {
+  describe('for version 1', () => {
+    const componentVersion = 1;
+    const componentProps = componentPropsV1;
+
+    it('returns a BinaryString representation of the component', () => {
+      const component = new PickupComponent({ version: componentVersion, ...componentProps });
+
+      const data = component.toBinary();
+
+      const expectedData = '10000000000000000000010100111001';
+
+      expect(data).toStrictEqual(expectedData);
+    });
+  });
+
+  describe('for version 2', () => {
+    const componentVersion = 2;
+    const componentProps = componentPropsV2;
+
+    it('returns a BinaryString representation of the component', () => {
+      const component = new PickupComponent({ version: componentVersion, ...componentProps });
+
+      const data = component.toBinary();
+
+      const expectedData =
+        '10000000000000000000010100111001000000000000000000000000000000010011111111111111111111110010111000011111100110000101000111101011101000100101001110010000000000000010000111101001000000000000000000100001010001010000000000000000001000100101001110010000000000000010000111101001000000000000000000100001010001010000000000000000000111111100000000000000000000000';
+
+      expect(data).toStrictEqual(expectedData);
+    });
+  });
+});
+
+describe('PickupComponent.write()', () => {
+  describe('for version 1', () => {
+    const componentVersion = 1;
+    const componentProps = componentPropsV1;
+
+    it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+      const component = new PickupComponent({ version: componentVersion, ...componentProps });
+
+      const writer = new BinaryWriter();
+      component.write(writer);
+
+      const data = writer.flush();
+
+      const expectedData =
+        '010101101011000100000011101101100000000000000000000000000010000010000000000000000000010100111001';
+
+      expect(data).toStrictEqual(expectedData);
+
+      const reader = new BinaryReader(data);
+
+      const hash = reader.readUnsignedInteger();
+      reader.readUnsignedInteger(); // PickupComponent data length.
+      const lastInteractorPlayerId = reader.readSignedInteger();
+
+      expect(hash).toStrictEqual(componentHash);
+      expect(lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+    });
+  });
+
+  describe('for version 2', () => {
+    const componentVersion = 2;
+    const componentProps = componentPropsV2;
+
+    it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+      const component = new PickupComponent({ version: componentVersion, ...componentProps });
+
+      const writer = new BinaryWriter();
+      component.write(writer);
+
+      const data = writer.flush();
+
+      const expectedData =
+        '010101101011000100000011101101100000000000000000000000010110000110000000000000000000010100111001000000000000000000000000000000010011111111111111111111110010111000011111100110000101000111101011101000100101001110010000000000000010000111101001000000000000000000100001010001010000000000000000001000100101001110010000000000000010000111101001000000000000000000100001010001010000000000000000000111111100000000000000000000000';
+
+      expect(data).toStrictEqual(expectedData);
+
+      const reader = new BinaryReader(data);
+
+      const hash = reader.readUnsignedInteger();
+      reader.readUnsignedInteger(); // PickupComponent data length.
+      const lastInteractorPlayerId = reader.readSignedInteger();
+      reader.readUnsignedInteger(); // GrabPointParameters array length.
+      const isNullBit = reader.readBoolean();
+      const grabPointIndex = reader.readSignedInteger();
+      const lastLinearPosition = reader.readFloat();
+      const lastPosition = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat()
+      };
+      const lastRotation = {
+        x: reader.readFloat(),
+        y: reader.readFloat(),
+        z: reader.readFloat(),
+        w: reader.readFloat()
+      };
+
+      expect(hash).toStrictEqual(componentHash);
+      expect(lastInteractorPlayerId).toStrictEqual(componentProps.lastInteractorPlayerId);
+      expect(isNullBit).toStrictEqual(false);
+      expect(grabPointIndex).toStrictEqual(componentProps.dockedMemory[0]?.grabPointIndex);
+      expect(lastLinearPosition).toBeCloseTo(componentProps.dockedMemory[0]?.lastLinearPosition ?? 0, 2);
+      expect(lastPosition).toStrictEqual(componentProps.dockedMemory[0]?.lastPosition);
+      expect(lastRotation).toStrictEqual(componentProps.dockedMemory[0]?.lastRotation);
+    });
+  });
+});
diff --git a/src/components/PickupComponent.ts b/src/components/PickupComponent.ts
new file mode 100644
index 0000000..319fed0
--- /dev/null
+++ b/src/components/PickupComponent.ts
@@ -0,0 +1,230 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+import type { Position } from '../types/Position.js';
+import type { Rotation } from '../types/Rotation.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type GrabPointParameters = null | {
+  grabPointIndex: number;
+  lastLinearPosition: number;
+  lastPosition: Position;
+  lastRotation: Rotation;
+};
+
+type PickupComponentPropsV1 = {
+  lastInteractorPlayerId?: number | undefined;
+  dockedMemory?: never;
+};
+
+type PickupComponentPropsV2 = {
+  lastInteractorPlayerId?: number | undefined;
+  dockedMemory?: GrabPointParameters[] | undefined;
+};
+
+export type PickupComponentProps = PickupComponentPropsV1 | PickupComponentPropsV2;
+
+/**
+ * @see [Class: `BasicDecayComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BasicDecayComponent.md)
+ * @since v3.0.0
+ * @version 2
+ *
+ * @example
+ * import { PickupComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 2;
+ * const component = new PickupComponent({ version: componentVersion });
+ */
+export class PickupComponent extends Component {
+  /**
+   * The ID of the player that last interacted with the prefab that this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { PickupComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupComponent({ version: componentVersion });
+   *
+   * const lastInteractorPlayerId = component.lastInteractorPlayerId;
+   * // `lastInteractorPlayerId` is `0`
+   */
+  lastInteractorPlayerId: number;
+
+  /**
+   * An array of `<GrabPointParameters>` that describes the orientation of prefabs when they were
+   * docked. Used to control in which orientation pickups should be held when grabbed from the dock
+   * attached to the same prefab this component is attached to.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PickupComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupComponent({ version: componentVersion });
+   *
+   * const dockedMemory = component.dockedMemory;
+   * // `dockedMemory` is `[]`
+   */
+  dockedMemory: GrabPointParameters[];
+
+  /**
+   * @see [Class: `BasicDecayComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BasicDecayComponent.md)
+   * @since v3.0.0
+   * @version 2
+   *
+   * @example
+   * import { PickupComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupComponent({ version: componentVersion });
+   */
+  constructor({ version, lastInteractorPlayerId, dockedMemory }: ComponentProps & PickupComponentProps) {
+    const hash = ComponentHash.Pickup;
+    const name = 'Pickup';
+
+    super({ hash, name, version });
+
+    this.lastInteractorPlayerId = lastInteractorPlayerId ?? 0;
+    this.dockedMemory = dockedMemory ?? [];
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): PickupComponent {
+    const props: ComponentProps & PickupComponentProps = { version };
+
+    /**
+     * @property {number} lastInteractorPlayerId
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.lastInteractorPlayerId = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {GrabPointParameters[]} dockedMemory
+     * @since v2
+     */
+    if (props.version >= 2) {
+      const grabPointParametersLength = reader.readUnsignedInteger();
+      props.dockedMemory = [];
+
+      for (let index = 0; index < grabPointParametersLength; ++index) {
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        const isNull = reader.readBoolean();
+
+        if (isNull) {
+          props.dockedMemory.push(null);
+          continue;
+        }
+
+        props.dockedMemory.push({
+          /**
+           * @property {number} grabPointIndex
+           * @since v2
+           */
+          grabPointIndex: reader.readSignedInteger(),
+
+          /**
+           * @property {float} lastLinearPosition
+           * @since v2
+           */
+          lastLinearPosition: reader.readFloat(),
+
+          /**
+           * @property {Position} lastPosition
+           * @since v2
+           */
+          lastPosition: {
+            x: reader.readFloat(),
+            y: reader.readFloat(),
+            z: reader.readFloat()
+          },
+
+          /**
+           * @property {Rotation} lastRotation
+           * @since v2
+           */
+          lastRotation: {
+            x: reader.readFloat(),
+            y: reader.readFloat(),
+            z: reader.readFloat(),
+            w: reader.readFloat()
+          }
+        });
+      }
+    }
+
+    return new PickupComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} lastInteractorPlayerId
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeSignedInteger(this.lastInteractorPlayerId);
+    }
+
+    /**
+     * @property {GrabPointParameters[]} dockedMemory
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.dockedMemory.length);
+
+      for (const grabPointParameters of this.dockedMemory) {
+        const isNull = grabPointParameters === null;
+
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        writer.writeBoolean(isNull);
+
+        if (!isNull) {
+          /**
+           * @property {number} grabPointIndex
+           * @since v2
+           */
+          writer.writeSignedInteger(grabPointParameters.grabPointIndex);
+
+          /**
+           * @property {float} lastLinearPosition
+           * @since v2
+           */
+          writer.writeFloat(grabPointParameters.lastLinearPosition);
+
+          /**
+           * @property {Position} lastPosition
+           * @since v2
+           */
+          writer.writeFloat(grabPointParameters.lastPosition.x);
+          writer.writeFloat(grabPointParameters.lastPosition.y);
+          writer.writeFloat(grabPointParameters.lastPosition.z);
+
+          /**
+           * @property {Rotation} lastRotation
+           * @since v2
+           */
+          writer.writeFloat(grabPointParameters.lastRotation.x);
+          writer.writeFloat(grabPointParameters.lastRotation.y);
+          writer.writeFloat(grabPointParameters.lastRotation.z);
+          writer.writeFloat(grabPointParameters.lastRotation.w);
+        }
+      }
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/PickupDockComponent.test.ts b/src/components/PickupDockComponent.test.ts
new file mode 100644
index 0000000..db2f4ee
--- /dev/null
+++ b/src/components/PickupDockComponent.test.ts
@@ -0,0 +1,137 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { PickupDockComponent } from './PickupDockComponent.js';
+
+const componentHash = ComponentHash.PickupDock;
+const componentName = 'PickupDock';
+const componentVersion = 2;
+const componentProps = {
+  dockedTypeHash: 1337,
+  quantity: -420,
+  childIndex: -69
+};
+
+describe('new PickupDockComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the PickupDockComponent class', () => {
+      const component = new PickupDockComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(PickupDockComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the PickupDockComponent class', () => {
+      const component = new PickupDockComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(PickupDockComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.dockedTypeHash).toStrictEqual(componentProps.dockedTypeHash);
+      expect(component.quantity).toStrictEqual(componentProps.quantity);
+      expect(component.childIndex).toStrictEqual(componentProps.childIndex);
+    });
+  });
+});
+
+describe('PickupDockComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      PickupDock: new PickupDockComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // PickupDockComponent hash.
+    reader.readUnsignedInteger(); // PickupDockComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the PickupDockComponent class', () => {
+    const component = PickupDockComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(PickupDockComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.dockedTypeHash).toStrictEqual(componentProps.dockedTypeHash);
+    expect(component.quantity).toStrictEqual(componentProps.quantity);
+    expect(component.childIndex).toStrictEqual(componentProps.childIndex);
+  });
+});
+
+describe('PickupDockComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new PickupDockComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '000000000000000000000101001110010111111111111111111111100101110001111111111111111111111110111011';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('PickupDockComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new PickupDockComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '1001101010000010011111001110001100000000000000000000000001100000000000000000000000000101001110010111111111111111111111100101110001111111111111111111111110111011';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // PickupDockComponent data length.
+    const dockedTypeHash = reader.readUnsignedInteger();
+    const quantity = reader.readSignedInteger();
+    const childIndex = reader.readSignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(dockedTypeHash).toStrictEqual(componentProps.dockedTypeHash);
+    expect(quantity).toStrictEqual(componentProps.quantity);
+    expect(childIndex).toStrictEqual(componentProps.childIndex);
+  });
+});
diff --git a/src/components/PickupDockComponent.ts b/src/components/PickupDockComponent.ts
new file mode 100644
index 0000000..6095381
--- /dev/null
+++ b/src/components/PickupDockComponent.ts
@@ -0,0 +1,152 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type PickupDockComponentPropsV2 = {
+  dockedTypeHash?: number | undefined;
+  quantity?: number | undefined;
+  childIndex?: number | undefined;
+};
+
+export type PickupDockComponentProps = PickupDockComponentPropsV2;
+
+/**
+ * @see [Class: `BasicDecayComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BasicDecayComponent.md)
+ * @since v3.0.0
+ * @version 2
+ *
+ * @example
+ * import { PickupDockComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 2;
+ * const component = new PickupDockComponent({ version: componentVersion });
+ */
+export class PickupDockComponent extends Component {
+  /**
+   * @since v2
+   *
+   * @example
+   * import { PickupDockComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupDockComponent({ version: componentVersion });
+   *
+   * const dockedTypeHash = component.dockedTypeHash;
+   * // `dockedTypeHash` is `0`
+   */
+  dockedTypeHash: number;
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { PickupDockComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupDockComponent({ version: componentVersion });
+   *
+   * const quantity = component.quantity;
+   * // `quantity` is `1`
+   */
+  quantity: number;
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { PickupDockComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupDockComponent({ version: componentVersion });
+   *
+   * const childIndex = component.childIndex;
+   * // `childIndex` is `0`
+   */
+  childIndex: number;
+
+  /**
+   * @see [Class: `BasicDecayComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/BasicDecayComponent.md)
+   * @since v3.0.0
+   * @version 2
+   *
+   * @example
+   * import { PickupDockComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PickupDockComponent({ version: componentVersion });
+   */
+  constructor({ version, dockedTypeHash, quantity, childIndex }: ComponentProps & PickupDockComponentProps) {
+    const hash = ComponentHash.PickupDock;
+    const name = 'PickupDock';
+
+    super({ hash, name, version });
+
+    this.dockedTypeHash = dockedTypeHash ?? 0;
+    this.quantity = quantity ?? 1;
+    this.childIndex = childIndex ?? 0;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): PickupDockComponent {
+    const props: ComponentProps & PickupDockComponentProps = { version };
+
+    /**
+     * @property {number} dockedTypeHash
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.dockedTypeHash = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} quantity
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.quantity = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {number} childIndex
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.childIndex = reader.readSignedInteger();
+    }
+
+    return new PickupDockComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} dockedTypeHash
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.dockedTypeHash);
+    }
+
+    /**
+     * @property {number} quantity
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.quantity);
+    }
+
+    /**
+     * @property {number} childIndex
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.childIndex);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/PopulationSpawnAreaComponent.test.ts b/src/components/PopulationSpawnAreaComponent.test.ts
new file mode 100644
index 0000000..382e52a
--- /dev/null
+++ b/src/components/PopulationSpawnAreaComponent.test.ts
@@ -0,0 +1,244 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import {
+  PopulationSpawnAreaComponent,
+  type PopulationSpawnAreaComponentProps
+} from './PopulationSpawnAreaComponent.js';
+
+const componentHash = ComponentHash.PopulationSpawnArea;
+const componentName = 'PopulationSpawnArea';
+const componentVersion = 2;
+
+const child = {
+  index: -420,
+  pointIndex: -69
+};
+
+const componentProps = {
+  definition: 1337,
+  isPopulationStarted: true,
+  children: [child],
+  maxPopulation: 420,
+  currentPopulation: 69,
+  checkPopulationTime: 133742069,
+  numberOfSpawnPoints: 42,
+  startingPopulation: 8,
+  isOneOff: false
+};
+
+describe('new PopulationSpawnAreaComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the PopulationSpawnAreaComponent class', () => {
+      const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(PopulationSpawnAreaComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the PopulationSpawnAreaComponent class', () => {
+      const component = new PopulationSpawnAreaComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(PopulationSpawnAreaComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.definition).toStrictEqual(componentProps.definition);
+      expect(component.isPopulationStarted).toStrictEqual(componentProps.isPopulationStarted);
+      expect(component.children).toStrictEqual(componentProps.children);
+      expect(component.maxPopulation).toStrictEqual(componentProps.maxPopulation);
+      expect(component.currentPopulation).toStrictEqual(componentProps.currentPopulation);
+      expect(component.checkPopulationTime).toStrictEqual(componentProps.checkPopulationTime);
+      expect(component.numberOfSpawnPoints).toStrictEqual(componentProps.numberOfSpawnPoints);
+      expect(component.startingPopulation).toStrictEqual(componentProps.startingPopulation);
+      expect(component.isOneOff).toStrictEqual(componentProps.isOneOff);
+    });
+  });
+});
+
+describe('PopulationSpawnAreaComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  describe('when all component props are given', () => {
+    const prefab = new Prefab('Grass_Clump', {
+      components: {
+        PopulationSpawnArea: new PopulationSpawnAreaComponent({ version: componentVersion, ...componentProps })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // PopulationSpawnAreaComponent hash.
+      reader.readUnsignedInteger(); // PopulationSpawnAreaComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns an instance of the PopulationSpawnAreaComponent class', () => {
+      const component = PopulationSpawnAreaComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(PopulationSpawnAreaComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.definition).toStrictEqual(componentProps.definition);
+      expect(component.isPopulationStarted).toStrictEqual(componentProps.isPopulationStarted);
+      expect(component.children).toStrictEqual(componentProps.children);
+      expect(component.maxPopulation).toStrictEqual(componentProps.maxPopulation);
+      expect(component.currentPopulation).toStrictEqual(componentProps.currentPopulation);
+      expect(component.checkPopulationTime).toStrictEqual(componentProps.checkPopulationTime);
+      expect(component.numberOfSpawnPoints).toStrictEqual(componentProps.numberOfSpawnPoints);
+      expect(component.startingPopulation).toStrictEqual(componentProps.startingPopulation);
+      expect(component.isOneOff).toStrictEqual(componentProps.isOneOff);
+    });
+  });
+
+  describe('when child is null', () => {
+    beforeEach(() => {
+      (componentProps as PopulationSpawnAreaComponentProps).children = [null];
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          PopulationSpawnArea: new PopulationSpawnAreaComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // PopulationSpawnAreaComponent hash.
+      reader.readUnsignedInteger(); // PopulationSpawnAreaComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.children = [child];
+    });
+
+    it('returns an instance of the PopulationSpawnAreaComponent class', () => {
+      const component = PopulationSpawnAreaComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(PopulationSpawnAreaComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.definition).toStrictEqual(componentProps.definition);
+      expect(component.isPopulationStarted).toStrictEqual(componentProps.isPopulationStarted);
+      expect(component.children).toStrictEqual(componentProps.children);
+      expect(component.maxPopulation).toStrictEqual(componentProps.maxPopulation);
+      expect(component.currentPopulation).toStrictEqual(componentProps.currentPopulation);
+      expect(component.checkPopulationTime).toStrictEqual(componentProps.checkPopulationTime);
+      expect(component.numberOfSpawnPoints).toStrictEqual(componentProps.numberOfSpawnPoints);
+      expect(component.startingPopulation).toStrictEqual(componentProps.startingPopulation);
+      expect(component.isOneOff).toStrictEqual(componentProps.isOneOff);
+    });
+  });
+});
+
+describe('PopulationSpawnAreaComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new PopulationSpawnAreaComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '00000000000000000000010100111001100000000000000000000000000000001001111111111111111111111001011100011111111111111111111111101110111000000000000000000000011010010010000000000000000000000001000101000001111111100010111101111101010000000000000000000000000000000010000000000000000000000000101010100000000000000000000000000010000';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('PopulationSpawnAreaComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new PopulationSpawnAreaComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '101101110000010000000011100111110000000000000000000000010100001100000000000000000000010100111001100000000000000000000000000000001001111111111111111111111001011100011111111111111111111111101110111000000000000000000000011010010010000000000000000000000001000101000001111111100010111101111101010000000000000000000000000000000010000000000000000000000000101010100000000000000000000000000010000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // PopulationSpawnAreaComponent data length.
+    const definition = reader.readUnsignedInteger();
+    const isPopulationStarted = reader.readBoolean();
+    reader.readUnsignedInteger(); // Children array length.
+    const isNullBit = reader.readBoolean();
+    const index = reader.readSignedInteger();
+    const pointIndex = reader.readSignedInteger();
+    const maxPopulation = reader.readSignedInteger();
+    const currentPopulation = reader.readSignedInteger();
+    const checkPopulationTime = reader.readUnsignedLong();
+    const numberOfSpawnPoints = reader.readSignedInteger();
+    const startingPopulation = reader.readSignedInteger();
+    const isOneOff = reader.readBoolean();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(definition).toStrictEqual(componentProps.definition);
+    expect(isPopulationStarted).toStrictEqual(componentProps.isPopulationStarted);
+    expect(isNullBit).toStrictEqual(false);
+    expect(index).toStrictEqual(componentProps.children[0]?.index);
+    expect(pointIndex).toStrictEqual(componentProps.children[0]?.pointIndex);
+    expect(maxPopulation).toStrictEqual(componentProps.maxPopulation);
+    expect(currentPopulation).toStrictEqual(componentProps.currentPopulation);
+    expect(checkPopulationTime).toStrictEqual(componentProps.checkPopulationTime);
+    expect(numberOfSpawnPoints).toStrictEqual(componentProps.numberOfSpawnPoints);
+    expect(startingPopulation).toStrictEqual(componentProps.startingPopulation);
+    expect(isOneOff).toStrictEqual(componentProps.isOneOff);
+  });
+});
diff --git a/src/components/PopulationSpawnAreaComponent.ts b/src/components/PopulationSpawnAreaComponent.ts
new file mode 100644
index 0000000..539d31f
--- /dev/null
+++ b/src/components/PopulationSpawnAreaComponent.ts
@@ -0,0 +1,425 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { PopulationDefinitionHash } from '../types/PopulationDefinitionHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type PopulationSaveDataChild = null | {
+  index: number;
+  pointIndex: number;
+};
+
+type PopulationSpawnAreaComponentPropsV2 = {
+  definition?: number | undefined;
+  isPopulationStarted?: boolean | undefined;
+  children?: PopulationSaveDataChild[] | undefined;
+  maxPopulation?: number | undefined;
+  currentPopulation?: number | undefined;
+  checkPopulationTime?: number | undefined;
+  numberOfSpawnPoints?: number | undefined;
+  startingPopulation?: number | undefined;
+  isOneOff?: boolean | undefined;
+};
+
+export type PopulationSpawnAreaComponentProps = PopulationSpawnAreaComponentPropsV2;
+
+/**
+ * @see [Class: `PopulationSpawnAreaComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/PopulationSpawnAreaComponent.md)
+ * @since v3.0.0
+ * @version 2
+ *
+ * @example
+ * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 2;
+ * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+ */
+export class PopulationSpawnAreaComponent extends Component {
+  /**
+   * The hash of the population to spawn in the `SpawnArea` component that is attached to the same prefab this component is attached to.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const definition = component.definition;
+   * // `definition` is `30040`
+   */
+  definition: number;
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const isPopulationStarted = component.isPopulationStarted;
+   * // `isPopulationStarted` is `true`
+   */
+  isPopulationStarted: boolean;
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const children = component.children;
+   * // `children` is `[]`
+   */
+  children: PopulationSaveDataChild[];
+
+  /**
+   * The maximum amount of spawned prefabs in this population.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const maxPopulation = component.maxPopulation;
+   * // `maxPopulation` is `20`
+   */
+  maxPopulation: number;
+
+  /**
+   * The current amount of spawned prefabs in this population.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const currentPopulation = component.currentPopulation;
+   * // `currentPopulation` is `5`
+   */
+  currentPopulation: number;
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const checkPopulationTime = component.checkPopulationTime;
+   * // `checkPopulationTime` is `852974979330`
+   */
+  checkPopulationTime: number;
+
+  /**
+   * The amount of spawn locations inside the `SpawnArea` component that is attached to the same prefab this component is attached to.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const numberOfSpawnPoints = component.numberOfSpawnPoints;
+   * // `numberOfSpawnPoints` is `40`
+   */
+  numberOfSpawnPoints: number;
+
+  /**
+   * The amount of spawned prefabs that this population begins with.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const startingPopulation = component.startingPopulation;
+   * // `startingPopulation` is `5`
+   */
+  startingPopulation: number;
+
+  /**
+   * Whether any removed prefabs from this population shouldn't be replaced after the server's respawn timer has elapsed.
+   *
+   * @since v2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   *
+   * const isOneOff = component.isOneOff;
+   * // `isOneOff` is `false`
+   */
+  isOneOff: boolean;
+
+  /**
+   * @see [Class: `PopulationSpawnAreaComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/PopulationSpawnAreaComponent.md)
+   * @since v3.0.0
+   * @version 2
+   *
+   * @example
+   * import { PopulationSpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new PopulationSpawnAreaComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    definition,
+    isPopulationStarted,
+    children,
+    maxPopulation,
+    currentPopulation,
+    checkPopulationTime,
+    numberOfSpawnPoints,
+    startingPopulation,
+    isOneOff
+  }: ComponentProps & PopulationSpawnAreaComponentProps) {
+    const hash = ComponentHash.PopulationSpawnArea;
+    const name = 'PopulationSpawnArea';
+
+    super({ hash, name, version });
+
+    this.definition = definition ?? PopulationDefinitionHash.StickPopulation;
+    this.isPopulationStarted = isPopulationStarted ?? true;
+    this.children = children ?? [];
+    this.maxPopulation = maxPopulation ?? 20;
+    this.currentPopulation = currentPopulation ?? 5;
+    this.checkPopulationTime = checkPopulationTime ?? 852974979330;
+    this.numberOfSpawnPoints = numberOfSpawnPoints ?? 40;
+    this.startingPopulation = startingPopulation ?? 5;
+    this.isOneOff = isOneOff ?? false;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): PopulationSpawnAreaComponent {
+    const props: ComponentProps & PopulationSpawnAreaComponentProps = { version };
+
+    /**
+     * @property {number} definition
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.definition = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {boolean} isPopulationStarted
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.isPopulationStarted = reader.readBoolean();
+    }
+
+    /**
+     * @property {PopulationSaveDataChild[]} children
+     * @since v2
+     */
+    if (props.version >= 2) {
+      const childrenLength = reader.readUnsignedInteger();
+      props.children = [];
+
+      for (let index = 0; index < childrenLength; ++index) {
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        const isNull = reader.readBoolean();
+
+        if (isNull) {
+          props.children.push(null);
+          continue;
+        }
+
+        props.children.push({
+          /**
+           * @property {number} index
+           * @since v2
+           */
+          index: reader.readSignedInteger(),
+
+          /**
+           * @property {number} pointIndex
+           * @since v2
+           */
+          pointIndex: reader.readSignedInteger()
+        });
+      }
+    }
+
+    /**
+     * @property {number} maxPopulation
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.maxPopulation = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {number} currentPopulation
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.currentPopulation = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {number} checkPopulationTime
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.checkPopulationTime = reader.readUnsignedLong();
+    }
+
+    /**
+     * @property {number} numberOfSpawnPoints
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.numberOfSpawnPoints = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {number} startingPopulation
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.startingPopulation = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {boolean} isOneOff
+     * @since v2
+     */
+    if (props.version >= 2) {
+      props.isOneOff = reader.readBoolean();
+    }
+
+    return new PopulationSpawnAreaComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} definition
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.definition);
+    }
+
+    /**
+     * @property {boolean} isPopulationStarted
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeBoolean(this.isPopulationStarted);
+    }
+
+    /**
+     * @property {PopulationSaveDataChild[]} children
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.children.length);
+
+      for (const populationSaveDataChild of this.children) {
+        const isNull = populationSaveDataChild === null;
+
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        writer.writeBoolean(isNull);
+
+        if (!isNull) {
+          /**
+           * @property {number} index
+           * @since v2
+           */
+          writer.writeSignedInteger(populationSaveDataChild.index);
+
+          /**
+           * @property {number} pointIndex
+           * @since v2
+           */
+          writer.writeSignedInteger(populationSaveDataChild.pointIndex);
+        }
+      }
+    }
+
+    /**
+     * @property {number} maxPopulation
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.maxPopulation);
+    }
+
+    /**
+     * @property {number} currentPopulation
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.currentPopulation);
+    }
+
+    /**
+     * @property {number} checkPopulationTime
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedLong(this.checkPopulationTime);
+    }
+
+    /**
+     * @property {number} numberOfSpawnPoints
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.numberOfSpawnPoints);
+    }
+
+    /**
+     * @property {number} startingPopulation
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeSignedInteger(this.startingPopulation);
+    }
+
+    /**
+     * @property {boolean} isOneOff
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeBoolean(this.isOneOff);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/SentGiftComponent.test.ts b/src/components/SentGiftComponent.test.ts
new file mode 100644
index 0000000..a7568e6
--- /dev/null
+++ b/src/components/SentGiftComponent.test.ts
@@ -0,0 +1,286 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { SentGiftComponent, type SentGiftComponentProps } from './SentGiftComponent.js';
+
+const componentHash = ComponentHash.SentGift;
+const componentName = 'SentGift';
+const componentVersion = 1;
+
+const gift = {
+  data: [1337],
+  messageSizeInBytes: 420,
+  hash: 69,
+  chunkVersioning: [42]
+};
+
+const senderTag = {
+  from: 1337,
+  to: 420
+};
+
+const componentProps = {
+  receiverName: 'Joel',
+  senderName: 'Ethyn Wyrmbane',
+  gifts: [gift],
+  senderTag: senderTag
+};
+
+describe('new SentGiftComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the SentGiftComponent class', () => {
+      const component = new SentGiftComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(SentGiftComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the SentGiftComponent class', () => {
+      const component = new SentGiftComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(SentGiftComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.receiverName).toStrictEqual(componentProps.receiverName);
+      expect(component.senderName).toStrictEqual(componentProps.senderName);
+      expect(component.gifts).toStrictEqual(componentProps.gifts);
+      expect(component.senderTag).toStrictEqual(componentProps.senderTag);
+    });
+  });
+});
+
+describe('SentGiftComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  describe('when all component props are given', () => {
+    const prefab = new Prefab('Grass_Clump', {
+      components: {
+        SentGift: new SentGiftComponent({ version: componentVersion, ...componentProps })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // SentGiftComponent hash.
+      reader.readUnsignedInteger(); // SentGiftComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns an instance of the SentGiftComponent class', () => {
+      const component = SentGiftComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(SentGiftComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.receiverName).toStrictEqual(componentProps.receiverName);
+      expect(component.senderName).toStrictEqual(componentProps.senderName);
+      expect(component.gifts).toStrictEqual(componentProps.gifts);
+      expect(component.senderTag).toStrictEqual(componentProps.senderTag);
+    });
+  });
+
+  describe('when gift is null', () => {
+    beforeEach(() => {
+      (componentProps as SentGiftComponentProps).gifts = [null];
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          SentGift: new SentGiftComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // SentGiftComponent hash.
+      reader.readUnsignedInteger(); // SentGiftComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.gifts = [gift];
+    });
+
+    it('returns an instance of the SentGiftComponent class', () => {
+      const component = SentGiftComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(SentGiftComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.receiverName).toStrictEqual(componentProps.receiverName);
+      expect(component.senderName).toStrictEqual(componentProps.senderName);
+      expect(component.gifts).toStrictEqual(componentProps.gifts);
+      expect(component.senderTag).toStrictEqual(componentProps.senderTag);
+    });
+  });
+
+  describe('when senderTag is null', () => {
+    beforeEach(() => {
+      (componentProps as SentGiftComponentProps).senderTag = null;
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          SentGift: new SentGiftComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // SentGiftComponent hash.
+      reader.readUnsignedInteger(); // SentGiftComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.senderTag = senderTag;
+    });
+
+    it('returns an instance of the SentGiftComponent class', () => {
+      const component = SentGiftComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(SentGiftComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.receiverName).toStrictEqual(componentProps.receiverName);
+      expect(component.senderName).toStrictEqual(componentProps.senderName);
+      expect(component.gifts).toStrictEqual(componentProps.gifts);
+      expect(component.senderTag).toStrictEqual(componentProps.senderTag);
+    });
+  });
+});
+
+describe('SentGiftComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new SentGiftComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '0000000000000100010010100110111101100101011011000000000000001110010001010111010001101000011110010111100101010111001000000110111001100001011000100110110101110010011011100110010100000000000000000000000000000001000000000000000000000000000000001000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101000000000000000000000000000000010000000000000000000000000010101001000000000000000000001010011100110000000000000000000000110100100';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('SentGiftComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new SentGiftComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '00100111011011011010011100100110000000000000000000000001110100100000000000000100010010100110111101100101011011000000000000001110010001010111010001101000011110010111100101010111001000000110111001100001011000100110110101110010011011100110010100000000000000000000000000000001000000000000000000000000000000001000000000000000000000101001110010000000000000000000000011010010000000000000000000000000001000101000000000000000000000000000000010000000000000000000000000010101001000000000000000000001010011100110000000000000000000000110100100';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // SentGiftComponent data length.
+    const receiverName = reader.readString();
+    const senderName = reader.readString();
+    reader.readUnsignedInteger(); // Gifts array length.
+    const isDataNullBit = reader.readBoolean();
+    reader.readUnsignedInteger(); // Gift data array length.
+    const dataUInt = reader.readUnsignedInteger();
+    const dataBytes = reader.readUnsignedInteger();
+    const dataHash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // Gift data chunk versioning array length.
+    const chunkVersioning = reader.readUnsignedInteger();
+    const isSenderTagNullBit = reader.readBoolean();
+    const tagFrom = reader.readSignedInteger();
+    const tagTo = reader.readSignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(receiverName).toStrictEqual(componentProps.receiverName);
+    expect(senderName).toStrictEqual(componentProps.senderName);
+    expect(isDataNullBit).toStrictEqual(false);
+    expect(dataUInt).toStrictEqual(componentProps.gifts[0]?.data[0]);
+    expect(dataBytes).toStrictEqual(componentProps.gifts[0]?.messageSizeInBytes);
+    expect(dataHash).toStrictEqual(componentProps.gifts[0]?.hash);
+    expect(chunkVersioning).toStrictEqual(componentProps.gifts[0]?.chunkVersioning[0]);
+    expect(isSenderTagNullBit).toStrictEqual(false);
+    expect(tagFrom).toStrictEqual(componentProps.senderTag.from);
+    expect(tagTo).toStrictEqual(componentProps.senderTag.to);
+  });
+});
diff --git a/src/components/SentGiftComponent.ts b/src/components/SentGiftComponent.ts
new file mode 100644
index 0000000..89c8873
--- /dev/null
+++ b/src/components/SentGiftComponent.ts
@@ -0,0 +1,358 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type Gift = null | {
+  data: number[];
+  messageSizeInBytes: number;
+  hash: number;
+  chunkVersioning: number[];
+};
+
+type SentGiftTag = null | {
+  from: number;
+  to: number;
+};
+
+type SentGiftComponentPropsV1 = {
+  receiverName?: string | undefined;
+  senderName?: string | undefined;
+  gifts?: Gift[] | undefined;
+  senderTag?: SentGiftTag | undefined;
+};
+
+export type SentGiftComponentProps = SentGiftComponentPropsV1;
+
+/**
+ * @see [Class: `SentGiftComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/SentGiftComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { SentGiftComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new SentGiftComponent({ version: componentVersion });
+ */
+export class SentGiftComponent extends Component {
+  /**
+   * Name of the player intended as the receiver of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { SentGiftComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SentGiftComponent({ version: componentVersion });
+   *
+   * const receiverName = component.receiverName;
+   * // `receiverName` is `''`
+   */
+  receiverName: string;
+
+  /**
+   * Name of the player intended as the sender of the prefab this component is attached to. This name will be displayed as a label on a gift box prefab.
+   *
+   * @since v1
+   *
+   * @example
+   * import { SentGiftComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SentGiftComponent({ version: componentVersion });
+   *
+   * const senderName = component.senderName;
+   * // `senderName` is `''`
+   */
+  senderName: string;
+
+  /**
+   * Array of gifts, which are prefab save strings.
+   *
+   * @since v1
+   *
+   * @example
+   * import { SentGiftComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SentGiftComponent({ version: componentVersion });
+   *
+   * const gifts = component.gifts;
+   * // `gifts` is `[]`
+   */
+  gifts: Gift[];
+
+  /**
+   * @since v1
+   *
+   * @example
+   * import { SentGiftComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SentGiftComponent({ version: componentVersion });
+   *
+   * const senderTag = component.senderTag;
+   * // `senderTag` is `null`
+   */
+  senderTag: SentGiftTag;
+
+  /**
+   * @see [Class: `SentGiftComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/SentGiftComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { SentGiftComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SentGiftComponent({ version: componentVersion });
+   */
+  constructor({ version, receiverName, senderName, gifts, senderTag }: ComponentProps & SentGiftComponentProps) {
+    const hash = ComponentHash.SentGift;
+    const name = 'SentGift';
+
+    super({ hash, name, version });
+
+    this.receiverName = receiverName ?? '';
+    this.senderName = senderName ?? '';
+    this.gifts = gifts ?? [];
+    this.senderTag = senderTag ?? null;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): SentGiftComponent {
+    const props: ComponentProps & SentGiftComponentProps = { version };
+
+    /**
+     * @property {string} receiverName
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.receiverName = reader.readString();
+    }
+
+    /**
+     * @property {string} senderName
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.senderName = reader.readString();
+    }
+
+    /**
+     * @property {Gift[]} gifts
+     * @since v1
+     */
+    if (props.version >= 1) {
+      const giftsLength = reader.readUnsignedInteger();
+      props.gifts = [];
+
+      for (let index = 0; index < giftsLength; ++index) {
+        /**
+         * @property {boolean} isNull
+         * @since v1
+         */
+        const isNull = reader.readBoolean();
+
+        if (isNull) {
+          props.gifts.push(null);
+          continue;
+        }
+
+        /**
+         * @property {number[]} data
+         * @since v1
+         */
+        const dataLength = reader.readUnsignedInteger();
+        const data: number[] = [];
+
+        for (let dataIndex = 0; dataIndex < dataLength; ++dataIndex) {
+          /**
+           * @property {number} data
+           * @since v1
+           */
+          data.push(reader.readUnsignedInteger());
+        }
+
+        /**
+         * @property {number} messageSizeInBytes
+         * @since v1
+         */
+
+        const messageSizeInBytes = reader.readUnsignedInteger();
+
+        /**
+         * @property {number} hash
+         * @since v1
+         */
+        const hash = reader.readUnsignedInteger();
+
+        /**
+         * @property {number[]} chunkVersioning
+         * @since v1
+         */
+        const chunkVersioningLength = reader.readUnsignedInteger();
+        const chunkVersioning: number[] = [];
+
+        for (let chunkVersioningIndex = 0; chunkVersioningIndex < chunkVersioningLength; ++chunkVersioningIndex) {
+          /**
+           * @property {number} chunkVersioning
+           * @since v1
+           */
+          chunkVersioning.push(reader.readUnsignedInteger());
+        }
+
+        props.gifts.push({
+          data,
+          messageSizeInBytes,
+          hash,
+          chunkVersioning
+        });
+      }
+    }
+
+    /**
+     * @property {SentGiftTag} senderTag
+     * @since v1
+     */
+    if (props.version >= 1) {
+      /**
+       * @property {boolean} isNull
+       * @since v1
+       */
+      const isNull = reader.readBoolean();
+
+      props.senderTag = isNull
+        ? null
+        : {
+            /**
+             * @property {number} from
+             * @since v1
+             */
+            from: reader.readSignedInteger(),
+
+            /**
+             * @property {number} to
+             * @since v1
+             */
+            to: reader.readSignedInteger()
+          };
+    }
+
+    return new SentGiftComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {string} receiverName
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeString(this.receiverName);
+    }
+
+    /**
+     * @property {string} senderName
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeString(this.senderName);
+    }
+
+    /**
+     * @property {Gift[]} gifts
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeUnsignedInteger(this.gifts.length);
+
+      for (const gift of this.gifts) {
+        const isNull = gift === null;
+
+        /**
+         * @property {boolean} isNull
+         * @since v1
+         */
+        writer.writeBoolean(isNull);
+
+        if (!isNull) {
+          /**
+           * @property {number[]} data
+           * @since v1
+           */
+          writer.writeUnsignedInteger(gift.data.length);
+
+          for (const data of gift.data) {
+            /**
+             * @property {number} data
+             * @since v1
+             */
+            writer.writeUnsignedInteger(data);
+          }
+
+          /**
+           * @property {number} messageSizeInBytes
+           * @since v1
+           */
+          writer.writeUnsignedInteger(gift.messageSizeInBytes);
+
+          /**
+           * @property {number} hash
+           * @since v1
+           */
+          writer.writeUnsignedInteger(gift.hash);
+
+          /**
+           * @property {number[]} chunkVersioning
+           * @since v1
+           */
+          writer.writeUnsignedInteger(gift.chunkVersioning.length);
+
+          for (const chunk of gift.chunkVersioning) {
+            /**
+             * @property {number} chunkVersioning
+             * @since v1
+             */
+            writer.writeUnsignedInteger(chunk);
+          }
+        }
+      }
+    }
+
+    /**
+     * @property {SentGiftTag} senderTag
+     * @since v1
+     */
+    if (version >= 1) {
+      const isNull = this.senderTag === null;
+
+      /**
+       * @property {boolean} isNull
+       * @since v1
+       */
+      writer.writeBoolean(isNull);
+
+      if (this.senderTag !== null) {
+        /**
+         * @property {number} from
+         * @since v1
+         */
+        writer.writeSignedInteger(this.senderTag.from);
+
+        /**
+         * @property {number} to
+         * @since v1
+         */
+        writer.writeSignedInteger(this.senderTag.to);
+      }
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/SlidingDoorComponent.test.ts b/src/components/SlidingDoorComponent.test.ts
new file mode 100644
index 0000000..971b166
--- /dev/null
+++ b/src/components/SlidingDoorComponent.test.ts
@@ -0,0 +1,125 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { SlidingDoorComponent } from './SlidingDoorComponent.js';
+
+const componentHash = ComponentHash.SlidingDoor;
+const componentName = 'SlidingDoor';
+const componentVersion = 1;
+const componentProps = {
+  isOpen: true
+};
+
+describe('new SlidingDoorComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the SlidingDoorComponent class', () => {
+      const component = new SlidingDoorComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(SlidingDoorComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the SlidingDoorComponent class', () => {
+      const component = new SlidingDoorComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(SlidingDoorComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.isOpen).toStrictEqual(componentProps.isOpen);
+    });
+  });
+});
+
+describe('SlidingDoorComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      SlidingDoor: new SlidingDoorComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // SlidingDoorComponent hash.
+    reader.readUnsignedInteger(); // SlidingDoorComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the SlidingDoorComponent class', () => {
+    const component = SlidingDoorComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(SlidingDoorComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.isOpen).toStrictEqual(componentProps.isOpen);
+  });
+});
+
+describe('SlidingDoorComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new SlidingDoorComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '1';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('SlidingDoorComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new SlidingDoorComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData = '11010101100101110100110110010100000000000000000000000000000000011';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // SlidingDoorComponent data length.
+    const isOpen = reader.readBoolean();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(isOpen).toStrictEqual(componentProps.isOpen);
+  });
+});
diff --git a/src/components/SlidingDoorComponent.ts b/src/components/SlidingDoorComponent.ts
new file mode 100644
index 0000000..c1dba09
--- /dev/null
+++ b/src/components/SlidingDoorComponent.ts
@@ -0,0 +1,90 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type SlidingDoorComponentPropsV1 = {
+  isOpen?: boolean | undefined;
+};
+
+export type SlidingDoorComponentProps = SlidingDoorComponentPropsV1;
+
+/**
+ * @see [Class: `SlidingDoorComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/SlidingDoorComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { SlidingDoorComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new SlidingDoorComponent({ version: componentVersion });
+ */
+export class SlidingDoorComponent extends Component {
+  /**
+   * Reveals the open state of this component's prefab.
+   *
+   * @since v1
+   *
+   * @example
+   * import { SlidingDoorComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SlidingDoorComponent({ version: componentVersion });
+   *
+   * const isOpen = component.isOpen;
+   * // `isOpen` is `false`
+   */
+  isOpen: boolean;
+
+  /**
+   * @see [Class: `SlidingDoorComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/SlidingDoorComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { SlidingDoorComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SlidingDoorComponent({ version: componentVersion });
+   */
+  constructor({ version, isOpen }: ComponentProps & SlidingDoorComponentProps) {
+    const hash = ComponentHash.SlidingDoor;
+    const name = 'SlidingDoor';
+
+    super({ hash, name, version });
+
+    this.isOpen = isOpen ?? false;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): SlidingDoorComponent {
+    const props: ComponentProps & SlidingDoorComponentProps = { version };
+
+    /**
+     * @property {boolean} isOpen
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isOpen = reader.readBoolean();
+    }
+
+    return new SlidingDoorComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {boolean} isOpen
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isOpen);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/SpawnAreaComponent.test.ts b/src/components/SpawnAreaComponent.test.ts
new file mode 100644
index 0000000..f3a5354
--- /dev/null
+++ b/src/components/SpawnAreaComponent.test.ts
@@ -0,0 +1,147 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { SpawnAreaComponent } from './SpawnAreaComponent.js';
+
+const componentHash = ComponentHash.SpawnArea;
+const componentName = 'SpawnArea';
+const componentVersion = 1;
+const componentProps = {
+  size: 13.37,
+  groundLayers: 420,
+  avoidLayers: 69,
+  isAligningNormal: true,
+  maxAcceptableAngleDot: 0.69
+};
+
+describe('new SpawnAreaComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the SpawnAreaComponent class', () => {
+      const component = new SpawnAreaComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(SpawnAreaComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the SpawnAreaComponent class', () => {
+      const component = new SpawnAreaComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(SpawnAreaComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.size).toBeCloseTo(componentProps.size, 2);
+      expect(component.groundLayers).toStrictEqual(componentProps.groundLayers);
+      expect(component.avoidLayers).toStrictEqual(componentProps.avoidLayers);
+      expect(component.isAligningNormal).toStrictEqual(componentProps.isAligningNormal);
+      expect(component.maxAcceptableAngleDot).toBeCloseTo(componentProps.maxAcceptableAngleDot, 2);
+    });
+  });
+});
+
+describe('SpawnAreaComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      SpawnArea: new SpawnAreaComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // SpawnAreaComponent hash.
+    reader.readUnsignedInteger(); // SpawnAreaComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the SpawnAreaComponent class', () => {
+    const component = SpawnAreaComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(SpawnAreaComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.size).toBeCloseTo(componentProps.size, 2);
+    expect(component.groundLayers).toStrictEqual(componentProps.groundLayers);
+    expect(component.avoidLayers).toStrictEqual(componentProps.avoidLayers);
+    expect(component.isAligningNormal).toStrictEqual(componentProps.isAligningNormal);
+    expect(component.maxAcceptableAngleDot).toBeCloseTo(componentProps.maxAcceptableAngleDot, 2);
+  });
+});
+
+describe('SpawnAreaComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new SpawnAreaComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '010000010101010111101011100001011000000000000000000000011010010010000000000000000000000001000101100111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('SpawnAreaComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new SpawnAreaComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '1001110000000011110011111110100000000000000000000000000010000001010000010101010111101011100001011000000000000000000000011010010010000000000000000000000001000101100111111001100001010001111010111';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // SpawnAreaComponent data length.
+    const size = reader.readFloat();
+    const groundLayers = reader.readSignedInteger();
+    const avoidLayers = reader.readSignedInteger();
+    const isAligningNormal = reader.readBoolean();
+    const maxAcceptableAngleDot = reader.readFloat();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(size).toBeCloseTo(componentProps.size, 2);
+    expect(groundLayers).toStrictEqual(componentProps.groundLayers);
+    expect(avoidLayers).toStrictEqual(componentProps.avoidLayers);
+    expect(isAligningNormal).toStrictEqual(componentProps.isAligningNormal);
+    expect(maxAcceptableAngleDot).toBeCloseTo(componentProps.maxAcceptableAngleDot, 2);
+  });
+});
diff --git a/src/components/SpawnAreaComponent.ts b/src/components/SpawnAreaComponent.ts
new file mode 100644
index 0000000..13541e5
--- /dev/null
+++ b/src/components/SpawnAreaComponent.ts
@@ -0,0 +1,225 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type SpawnAreaComponentPropsV1 = {
+  size?: number | undefined;
+  groundLayers?: number | undefined;
+  avoidLayers?: number | undefined;
+  isAligningNormal?: boolean | undefined;
+  maxAcceptableAngleDot?: number | undefined;
+};
+
+export type SpawnAreaComponentProps = SpawnAreaComponentPropsV1;
+
+/**
+ * @see [Class: `SpawnAreaComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/SpawnAreaComponent.md)
+ * @since v3.0.0
+ * @version 1
+ *
+ * @example
+ * import { SpawnAreaComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 1;
+ * const component = new SpawnAreaComponent({ version: componentVersion });
+ */
+export class SpawnAreaComponent extends Component {
+  /**
+   * The size (in metres) of the spawn area of the prefab this component is attached to.
+   *
+   * @since v1
+   *
+   * @example
+   * import { SpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SpawnAreaComponent({ version: componentVersion });
+   *
+   * const size = component.size;
+   * // `size` is `5`
+   */
+  size: number;
+
+  /**
+   * @since v1
+   *
+   * @example
+   * import { SpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SpawnAreaComponent({ version: componentVersion });
+   *
+   * const groundLayers = component.groundLayers;
+   * // `groundLayers` is `1280`
+   */
+  groundLayers: number;
+
+  /**
+   * @since v1
+   *
+   * @example
+   * import { SpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SpawnAreaComponent({ version: componentVersion });
+   *
+   * const avoidLayers = component.avoidLayers;
+   * // `avoidLayers` is `8721`
+   */
+  avoidLayers: number;
+
+  /**
+   * @since v1
+   *
+   * @example
+   * import { SpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SpawnAreaComponent({ version: componentVersion });
+   *
+   * const isAligningNormal = component.isAligningNormal;
+   * // `isAligningNormal` is `false`
+   */
+  isAligningNormal: boolean;
+
+  /**
+   * @since v1
+   *
+   * @example
+   * import { SpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SpawnAreaComponent({ version: componentVersion });
+   *
+   * const maxAcceptableAngleDot = component.maxAcceptableAngleDot;
+   * // `maxAcceptableAngleDot` is `-1`
+   */
+  maxAcceptableAngleDot: number;
+
+  /**
+   * @see [Class: `SpawnAreaComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/SpawnAreaComponent.md)
+   * @since v3.0.0
+   * @version 1
+   *
+   * @example
+   * import { SpawnAreaComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 1;
+   * const component = new SpawnAreaComponent({ version: componentVersion });
+   */
+  constructor({
+    version,
+    size,
+    groundLayers,
+    avoidLayers,
+    isAligningNormal,
+    maxAcceptableAngleDot
+  }: ComponentProps & SpawnAreaComponentProps) {
+    const hash = ComponentHash.SpawnArea;
+    const name = 'SpawnArea';
+
+    super({ hash, name, version });
+
+    this.size = size ?? 5;
+    this.groundLayers = groundLayers ?? 1280;
+    this.avoidLayers = avoidLayers ?? 8721;
+    this.isAligningNormal = isAligningNormal ?? false;
+    this.maxAcceptableAngleDot = maxAcceptableAngleDot ?? -1;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): SpawnAreaComponent {
+    const props: ComponentProps & SpawnAreaComponentProps = { version };
+
+    /**
+     * @property {float} size
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.size = reader.readFloat();
+    }
+
+    /**
+     * @property {number} groundLayers
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.groundLayers = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {number} avoidLayers
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.avoidLayers = reader.readSignedInteger();
+    }
+
+    /**
+     * @property {boolean} isAligningNormal
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.isAligningNormal = reader.readBoolean();
+    }
+
+    /**
+     * @property {float} maxAcceptableAngleDot
+     * @since v1
+     */
+    if (props.version >= 1) {
+      props.maxAcceptableAngleDot = reader.readFloat();
+    }
+
+    return new SpawnAreaComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {float} size
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.size);
+    }
+
+    /**
+     * @property {number} groundLayers
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeSignedInteger(this.groundLayers);
+    }
+
+    /**
+     * @property {number} avoidLayers
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeSignedInteger(this.avoidLayers);
+    }
+
+    /**
+     * @property {boolean} isAligningNormal
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeBoolean(this.isAligningNormal);
+    }
+
+    /**
+     * @property {float} maxAcceptableAngleDot
+     * @since v1
+     */
+    if (version >= 1) {
+      writer.writeFloat(this.maxAcceptableAngleDot);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/StatManagerComponent.test.ts b/src/components/StatManagerComponent.test.ts
new file mode 100644
index 0000000..6ed37b8
--- /dev/null
+++ b/src/components/StatManagerComponent.test.ts
@@ -0,0 +1,443 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { StatManagerComponent, type StatManagerComponentProps } from './StatManagerComponent.js';
+
+const componentHash = ComponentHash.StatManager;
+const componentName = 'StatManager';
+const componentVersion = 2;
+
+const stat = {
+  hash: 1337,
+  baseFlat: 0.69
+};
+
+const timedModifier = {
+  hash: 1337,
+  value: 0.69,
+  isMultiplier: true,
+  time: 133742069
+};
+
+const indirectModifierSaveData = {
+  valueOverDurationHash: 1337,
+  baseValue: 0.69,
+  duration: 133742069,
+  tick: 420
+};
+
+const indirectStatModifier = {
+  hash: 1337,
+  time: 133742069,
+  modifiers: [indirectModifierSaveData]
+};
+
+const componentProps = {
+  stats: [stat],
+  modifiers: [timedModifier],
+  indirectStatModifiers: [indirectStatModifier]
+};
+
+describe('new StatManagerComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the StatManagerComponent class', () => {
+      const component = new StatManagerComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(StatManagerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the StatManagerComponent class', () => {
+      const component = new StatManagerComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(StatManagerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.stats[0]?.hash).toStrictEqual(componentProps.stats[0]?.hash);
+      expect(component.stats[0]?.baseFlat).toBeCloseTo(componentProps.stats[0]?.baseFlat ?? 0, 2);
+      expect(component.modifiers[0]?.hash).toStrictEqual(componentProps.modifiers[0]?.hash);
+      expect(component.modifiers[0]?.value).toBeCloseTo(componentProps.modifiers[0]?.value ?? 0, 2);
+      expect(component.modifiers[0]?.isMultiplier).toStrictEqual(componentProps.modifiers[0]?.isMultiplier);
+      expect(component.modifiers[0]?.time).toStrictEqual(componentProps.modifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.hash).toStrictEqual(componentProps.indirectStatModifiers[0]?.hash);
+      expect(component.indirectStatModifiers[0]?.time).toStrictEqual(componentProps.indirectStatModifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.baseValue).toBeCloseTo(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.baseValue ?? 0,
+        2
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.duration).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.duration
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.tick).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.tick
+      );
+    });
+  });
+});
+
+describe('StatManagerComponent.fromBinary()', () => {
+  describe('when all component props are given', () => {
+    let fastForwardedReader: BinaryReader;
+
+    const prefab = new Prefab('Grass_Clump', {
+      components: {
+        StatManager: new StatManagerComponent({ version: componentVersion, ...componentProps })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // StatManagerComponent hash.
+      reader.readUnsignedInteger(); // StatManagerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns an instance of the StatManagerComponent class', () => {
+      const component = StatManagerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(StatManagerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.stats[0]?.hash).toStrictEqual(componentProps.stats[0]?.hash);
+      expect(component.stats[0]?.baseFlat).toBeCloseTo(componentProps.stats[0]?.baseFlat ?? 0, 2);
+      expect(component.modifiers[0]?.hash).toStrictEqual(componentProps.modifiers[0]?.hash);
+      expect(component.modifiers[0]?.value).toBeCloseTo(componentProps.modifiers[0]?.value ?? 0, 2);
+      expect(component.modifiers[0]?.isMultiplier).toStrictEqual(componentProps.modifiers[0]?.isMultiplier);
+      expect(component.modifiers[0]?.time).toStrictEqual(componentProps.modifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.hash).toStrictEqual(componentProps.indirectStatModifiers[0]?.hash);
+      expect(component.indirectStatModifiers[0]?.time).toStrictEqual(componentProps.indirectStatModifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.baseValue).toBeCloseTo(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.baseValue ?? 0,
+        2
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.duration).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.duration
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.tick).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.tick
+      );
+    });
+  });
+
+  describe('when stat is null', () => {
+    let fastForwardedReader: BinaryReader;
+
+    beforeEach(() => {
+      (componentProps as StatManagerComponentProps).stats = [null];
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          StatManager: new StatManagerComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // StatManagerComponent hash.
+      reader.readUnsignedInteger(); // StatManagerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.stats = [stat];
+    });
+
+    it('returns an instance of the StatManagerComponent class', () => {
+      const component = StatManagerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(StatManagerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.stats[0]).toStrictEqual(null);
+      expect(component.modifiers[0]?.hash).toStrictEqual(componentProps.modifiers[0]?.hash);
+      expect(component.modifiers[0]?.value).toBeCloseTo(componentProps.modifiers[0]?.value ?? 0, 2);
+      expect(component.modifiers[0]?.isMultiplier).toStrictEqual(componentProps.modifiers[0]?.isMultiplier);
+      expect(component.modifiers[0]?.time).toStrictEqual(componentProps.modifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.hash).toStrictEqual(componentProps.indirectStatModifiers[0]?.hash);
+      expect(component.indirectStatModifiers[0]?.time).toStrictEqual(componentProps.indirectStatModifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.baseValue).toBeCloseTo(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.baseValue ?? 0,
+        2
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.duration).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.duration
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.tick).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.tick
+      );
+    });
+  });
+
+  describe('when timedModifier is null', () => {
+    let fastForwardedReader: BinaryReader;
+
+    beforeEach(() => {
+      (componentProps as StatManagerComponentProps).modifiers = [null];
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          StatManager: new StatManagerComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // StatManagerComponent hash.
+      reader.readUnsignedInteger(); // StatManagerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.modifiers = [timedModifier];
+    });
+
+    it('returns an instance of the StatManagerComponent class', () => {
+      const component = StatManagerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(StatManagerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.stats[0]?.hash).toStrictEqual(componentProps.stats[0]?.hash);
+      expect(component.stats[0]?.baseFlat).toBeCloseTo(componentProps.stats[0]?.baseFlat ?? 0, 2);
+      expect(component.modifiers[0]).toStrictEqual(null);
+      expect(component.indirectStatModifiers[0]?.hash).toStrictEqual(componentProps.indirectStatModifiers[0]?.hash);
+      expect(component.indirectStatModifiers[0]?.time).toStrictEqual(componentProps.indirectStatModifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.baseValue).toBeCloseTo(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.baseValue ?? 0,
+        2
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.duration).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.duration
+      );
+      expect(component.indirectStatModifiers[0]?.modifiers[0]?.tick).toStrictEqual(
+        componentProps.indirectStatModifiers[0]?.modifiers[0]?.tick
+      );
+    });
+  });
+
+  describe('when indirectStatModifier is null', () => {
+    let fastForwardedReader: BinaryReader;
+
+    beforeEach(() => {
+      (componentProps as StatManagerComponentProps).indirectStatModifiers = [null];
+
+      const prefab = new Prefab('Grass_Clump', {
+        components: {
+          StatManager: new StatManagerComponent({ version: componentVersion, ...componentProps })
+        }
+      });
+
+      const saveString = prefab.toSaveString();
+
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // StatManagerComponent hash.
+      reader.readUnsignedInteger(); // StatManagerComponent data length.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      componentProps.indirectStatModifiers = [indirectStatModifier];
+    });
+
+    it('returns an instance of the StatManagerComponent class', () => {
+      const component = StatManagerComponent.fromBinary(fastForwardedReader, componentVersion);
+
+      expect(component).toBeInstanceOf(StatManagerComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.stats[0]?.hash).toStrictEqual(componentProps.stats[0]?.hash);
+      expect(component.stats[0]?.baseFlat).toBeCloseTo(componentProps.stats[0]?.baseFlat ?? 0, 2);
+      expect(component.modifiers[0]?.hash).toStrictEqual(componentProps.modifiers[0]?.hash);
+      expect(component.modifiers[0]?.value).toBeCloseTo(componentProps.modifiers[0]?.value ?? 0, 2);
+      expect(component.modifiers[0]?.isMultiplier).toStrictEqual(componentProps.modifiers[0]?.isMultiplier);
+      expect(component.modifiers[0]?.time).toStrictEqual(componentProps.modifiers[0]?.time);
+      expect(component.indirectStatModifiers[0]).toStrictEqual(null);
+    });
+  });
+});
+
+describe('StatManagerComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new StatManagerComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData =
+      '00000000000000000000000000000001000000000000000000000010100111001001111110011000010100011110101110000000000000000000000000000000100000000000000000000001010011100100111111001100001010001111010111100000111111110001011110111110101000000000000000000000000000000000000000000000000000000000000000100000000000000000000001010011100100000111111110001011110111110101000000000000000000000000000000000000000000000000000000000000000100000000000000000000010100111001001111110011000010100011110101110000011111111000101111011111010100000000000000000000000110100100';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('StatManagerComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new StatManagerComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '100110001100110011101110000000010000000000000000000000100010010000000000000000000000000000000001000000000000000000000010100111001001111110011000010100011110101110000000000000000000000000000000100000000000000000000001010011100100111111001100001010001111010111100000111111110001011110111110101000000000000000000000000000000000000000000000000000000000000000100000000000000000000001010011100100000111111110001011110111110101000000000000000000000000000000000000000000000000000000000000000100000000000000000000010100111001001111110011000010100011110101110000011111111000101111011111010100000000000000000000000110100100';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // StatManagerComponent data length.
+    reader.readUnsignedInteger(); // Stat array length.
+    const isStatNullBit = reader.readBoolean();
+    const statHash = reader.readUnsignedInteger();
+    const statBaseFlat = reader.readFloat();
+    reader.readUnsignedInteger(); // Modifier array length.
+    const isModifierNullBit = reader.readBoolean();
+    const modifierHash = reader.readUnsignedInteger();
+    const modifierValue = reader.readFloat();
+    const modifierIsMultiplier = reader.readBoolean();
+    const modifierTime = reader.readUnsignedLong();
+    reader.readUnsignedInteger(); // IndirectStatModifiers array length.
+    const isIndirectStatModifiersNullBit = reader.readBoolean();
+    const indirectHash = reader.readUnsignedInteger();
+    const indirectTime = reader.readUnsignedLong();
+    reader.readUnsignedInteger(); // IndirectModifierSaveData array length.
+    const saveHash = reader.readUnsignedInteger();
+    const saveBaseValue = reader.readFloat();
+    const saveDuration = reader.readUnsignedInteger();
+    const saveTick = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(isStatNullBit).toStrictEqual(false);
+    expect(statHash).toStrictEqual(componentProps.stats[0]?.hash);
+    expect(statBaseFlat).toBeCloseTo(componentProps.stats[0]?.baseFlat ?? 0, 2);
+    expect(isModifierNullBit).toStrictEqual(false);
+    expect(modifierHash).toStrictEqual(componentProps.modifiers[0]?.hash);
+    expect(modifierValue).toBeCloseTo(componentProps.modifiers[0]?.value ?? 0, 2);
+    expect(modifierIsMultiplier).toStrictEqual(componentProps.modifiers[0]?.isMultiplier);
+    expect(modifierTime).toStrictEqual(componentProps.modifiers[0]?.time);
+    expect(isIndirectStatModifiersNullBit).toStrictEqual(false);
+    expect(indirectHash).toStrictEqual(componentProps.indirectStatModifiers[0]?.hash);
+    expect(indirectTime).toStrictEqual(componentProps.indirectStatModifiers[0]?.time);
+    expect(saveHash).toStrictEqual(componentProps.indirectStatModifiers[0]?.modifiers[0]?.valueOverDurationHash);
+    expect(saveBaseValue).toBeCloseTo(componentProps.indirectStatModifiers[0]?.modifiers[0]?.baseValue ?? 0, 2);
+    expect(saveDuration).toStrictEqual(componentProps.indirectStatModifiers[0]?.modifiers[0]?.duration);
+    expect(saveTick).toStrictEqual(componentProps.indirectStatModifiers[0]?.modifiers[0]?.tick);
+  });
+});
diff --git a/src/components/StatManagerComponent.ts b/src/components/StatManagerComponent.ts
new file mode 100644
index 0000000..abfc898
--- /dev/null
+++ b/src/components/StatManagerComponent.ts
@@ -0,0 +1,432 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type Stat = null | {
+  hash: number;
+  baseFlat: number;
+};
+
+type TimedModifier = null | {
+  hash: number;
+  value: number;
+  isMultiplier: boolean;
+  time: number;
+};
+
+type IndirectModifierSaveData = {
+  valueOverDurationHash: number;
+  baseValue: number;
+  duration: number;
+  tick: number;
+};
+
+type IndirectStatModifier = null | {
+  hash: number;
+  time: number;
+  modifiers: IndirectModifierSaveData[];
+};
+
+type StatManagerComponentPropsV2 = {
+  stats?: Stat[] | undefined;
+  modifiers?: TimedModifier[] | undefined;
+  indirectStatModifiers?: IndirectStatModifier[] | undefined;
+};
+
+export type StatManagerComponentProps = StatManagerComponentPropsV2;
+
+/**
+ * @see [Class: `StatManagerComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/StatManagerComponent.md)
+ * @since v3.0.0
+ * @version 2
+ *
+ * @example
+ * import { StatManagerComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 2;
+ * const component = new StatManagerComponent({ version: componentVersion });
+ */
+export class StatManagerComponent extends Component {
+  /**
+   * @since v2
+   *
+   * @example
+   * import { StatManagerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new StatManagerComponent({ version: componentVersion });
+   *
+   * const stats = component.stats;
+   * // `stats` is `[]`
+   */
+  stats: Stat[];
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { StatManagerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new StatManagerComponent({ version: componentVersion });
+   *
+   * const modifiers = component.modifiers;
+   * // `modifiers` is `[]`
+   */
+  modifiers: TimedModifier[];
+
+  /**
+   * @since v2
+   *
+   * @example
+   * import { StatManagerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new StatManagerComponent({ version: componentVersion });
+   *
+   * const indirectStatModifiers = component.indirectStatModifiers;
+   * // `indirectStatModifiers` is `[]`
+   */
+  indirectStatModifiers: IndirectStatModifier[];
+
+  /**
+   * @see [Class: `StatManagerComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/StatManagerComponent.md)
+   * @since v3.0.0
+   * @version 2
+   *
+   * @example
+   * import { StatManagerComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 2;
+   * const component = new StatManagerComponent({ version: componentVersion });
+   */
+  constructor({ version, stats, modifiers, indirectStatModifiers }: ComponentProps & StatManagerComponentProps) {
+    const hash = ComponentHash.StatManager;
+    const name = 'StatManager';
+
+    super({ hash, name, version });
+
+    this.stats = stats ?? [];
+    this.modifiers = modifiers ?? [];
+    this.indirectStatModifiers = indirectStatModifiers ?? [];
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): StatManagerComponent {
+    const props: ComponentProps & StatManagerComponentProps = { version };
+
+    /**
+     * @property {Stat[]} stats
+     * @since v2
+     */
+    if (props.version >= 2) {
+      const statsLength = reader.readUnsignedInteger();
+      props.stats = [];
+
+      for (let index = 0; index < statsLength; ++index) {
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        const isNull = reader.readBoolean();
+
+        if (isNull) {
+          props.stats.push(null);
+          continue;
+        }
+
+        props.stats.push({
+          /**
+           * @property {number} hash
+           * @since v2
+           */
+          hash: reader.readUnsignedInteger(),
+
+          /**
+           * @property {float} baseFlat
+           * @since v2
+           */
+          baseFlat: reader.readFloat()
+        });
+      }
+    }
+
+    /**
+     * @property {TimedModifier[]} modifiers
+     * @since v2
+     */
+    if (props.version >= 2) {
+      const modifiersLength = reader.readUnsignedInteger();
+      props.modifiers = [];
+
+      for (let index = 0; index < modifiersLength; ++index) {
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        const isNull = reader.readBoolean();
+
+        if (isNull) {
+          props.modifiers.push(null);
+          continue;
+        }
+
+        props.modifiers.push({
+          /**
+           * @property {number} hash
+           * @since v2
+           */
+          hash: reader.readUnsignedInteger(),
+
+          /**
+           * @property {float} value
+           * @since v2
+           */
+          value: reader.readFloat(),
+
+          /**
+           * @property {boolean} isMultiplier
+           * @since v2
+           */
+          isMultiplier: reader.readBoolean(),
+
+          /**
+           * @property {number} time
+           * @since v2
+           */
+          time: reader.readUnsignedLong()
+        });
+      }
+    }
+
+    /**
+     * @property {IndirectStatModifier[]} indirectStatModifiers
+     * @since v2
+     */
+    if (props.version >= 2) {
+      const indirectStatModifiersLength = reader.readUnsignedInteger();
+      props.indirectStatModifiers = [];
+
+      for (let index = 0; index < indirectStatModifiersLength; ++index) {
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        const isNull = reader.readBoolean();
+
+        if (isNull) {
+          props.indirectStatModifiers.push(null);
+          continue;
+        }
+
+        /**
+         * @property {number} hash
+         * @since v2
+         */
+        const hash = reader.readUnsignedInteger();
+
+        /**
+         * @property {number} time
+         * @since v2
+         */
+        const time = reader.readUnsignedLong();
+
+        /**
+         * @property {IndirectModifierSaveData[]} indirectModifiersSaveData
+         * @since v2
+         */
+        const indirectModifiersSaveDataLength = reader.readUnsignedInteger();
+        const indirectModifiersSaveData: IndirectModifierSaveData[] = [];
+
+        for (
+          let indirectModifiersSaveDataIndex = 0;
+          indirectModifiersSaveDataIndex < indirectModifiersSaveDataLength;
+          ++indirectModifiersSaveDataIndex
+        ) {
+          indirectModifiersSaveData.push({
+            /**
+             * @property {number} valueOverDurationHash
+             * @since v2
+             */
+            valueOverDurationHash: reader.readUnsignedInteger(),
+
+            /**
+             * @property {float} baseValue
+             * @since v2
+             */
+            baseValue: reader.readFloat(),
+
+            /**
+             * @property {number} duration
+             * @since v2
+             */
+            duration: reader.readUnsignedInteger(),
+
+            /**
+             * @property {number} tick
+             * @since v2
+             */
+            tick: reader.readUnsignedInteger()
+          });
+        }
+
+        props.indirectStatModifiers.push({
+          hash,
+          time,
+          modifiers: indirectModifiersSaveData
+        });
+      }
+    }
+
+    return new StatManagerComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {Stat[]} stats
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.stats.length);
+
+      for (const stat of this.stats) {
+        const isNull = stat === null;
+
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        writer.writeBoolean(isNull);
+
+        if (!isNull) {
+          /**
+           * @property {number} hash
+           * @since v2
+           */
+          writer.writeUnsignedInteger(stat.hash);
+
+          /**
+           * @property {float} baseFlat
+           * @since v2
+           */
+          writer.writeFloat(stat.baseFlat);
+        }
+      }
+    }
+
+    /**
+     * @property {TimedModifier[]} modifiers
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.modifiers.length);
+
+      for (const modifier of this.modifiers) {
+        const isNull = modifier === null;
+
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        writer.writeBoolean(isNull);
+
+        if (!isNull) {
+          /**
+           * @property {number} hash
+           * @since v2
+           */
+          writer.writeUnsignedInteger(modifier.hash);
+
+          /**
+           * @property {float} value
+           * @since v2
+           */
+          writer.writeFloat(modifier.value);
+
+          /**
+           * @property {boolean} isMultiplier
+           * @since v2
+           */
+          writer.writeBoolean(modifier.isMultiplier);
+
+          /**
+           * @property {number} time
+           * @since v2
+           */
+          writer.writeUnsignedLong(modifier.time);
+        }
+      }
+    }
+
+    /**
+     * @property {IndirectStatModifier[]} indirectStatModifiers
+     * @since v2
+     */
+    if (version >= 2) {
+      writer.writeUnsignedInteger(this.indirectStatModifiers.length);
+
+      for (const indirectStatModifier of this.indirectStatModifiers) {
+        const isNull = indirectStatModifier === null;
+
+        /**
+         * @property {boolean} isNull
+         * @since v2
+         */
+        writer.writeBoolean(isNull);
+
+        if (!isNull) {
+          /**
+           * @property {number} hash
+           * @since v2
+           */
+          writer.writeUnsignedInteger(indirectStatModifier.hash);
+
+          /**
+           * @property {number} time
+           * @since v2
+           */
+          writer.writeUnsignedLong(indirectStatModifier.time);
+
+          /**
+           * @property {IndirectModifierSaveData[]} indirectModifiersSaveData
+           * @since v2
+           */
+          writer.writeUnsignedInteger(indirectStatModifier.modifiers.length);
+
+          for (const modifier of indirectStatModifier.modifiers) {
+            /**
+             * @property {number} valueOverDurationHash
+             * @since v2
+             */
+            writer.writeUnsignedInteger(modifier.valueOverDurationHash);
+
+            /**
+             * @property {float} baseValue
+             * @since v2
+             */
+            writer.writeFloat(modifier.baseValue);
+
+            /**
+             * @property {number} duration
+             * @since v2
+             */
+            writer.writeUnsignedInteger(modifier.duration);
+
+            /**
+             * @property {number} tick
+             * @since v2
+             */
+            writer.writeUnsignedInteger(modifier.tick);
+          }
+        }
+      }
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/UnsupportedComponent.test.ts b/src/components/UnsupportedComponent.test.ts
new file mode 100644
index 0000000..7c5420e
--- /dev/null
+++ b/src/components/UnsupportedComponent.test.ts
@@ -0,0 +1,155 @@
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { UnsupportedComponent } from './UnsupportedComponent.js';
+
+describe('new UnsupportedComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the UnsupportedComponent class', () => {
+      const componentHash = 1337;
+      const componentName = 'topkek';
+      const componentVersion = 1;
+      const componentData = '11110111001100010000' as BinaryString;
+
+      const component = new UnsupportedComponent({
+        hash: componentHash,
+        name: componentName,
+        version: componentVersion,
+        rawData: componentData
+      });
+
+      expect(component).toBeInstanceOf(UnsupportedComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.rawData).toStrictEqual(componentData);
+    });
+  });
+});
+
+describe('UnsupportedComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+  let componentDataLength: number;
+  const componentHash = ComponentHash.RandomSpawnRectangle;
+  const componentName = 'RandomSpawnRectangle';
+  const componentVersion = 1;
+  const componentData = '11110111001100010000' as BinaryString;
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      RandomSpawnRectangle: new UnsupportedComponent({
+        hash: componentHash,
+        name: componentName,
+        version: componentVersion,
+        rawData: componentData
+      })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // UnsupportedComponent hash.
+    const dataLength = reader.readUnsignedInteger(); // UnsupportedComponent data length.
+
+    fastForwardedReader = reader;
+    componentDataLength = dataLength;
+  });
+
+  it('returns an instance of the UnsupportedComponent class', () => {
+    const component = UnsupportedComponent.fromBinary(
+      fastForwardedReader,
+      componentVersion,
+      componentHash,
+      componentName,
+      componentDataLength
+    );
+
+    expect(component).toBeInstanceOf(UnsupportedComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.rawData).toStrictEqual(componentData);
+  });
+});
+
+describe('UnsupportedComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const componentHash = 1337;
+    const componentName = 'topkek';
+    const componentVersion = 1;
+    const componentData = '11110111001100010000' as BinaryString;
+
+    const component = new UnsupportedComponent({
+      hash: componentHash,
+      name: componentName,
+      version: componentVersion,
+      rawData: componentData
+    });
+
+    const data = component.toBinary();
+
+    const expectedData = componentData;
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('UnsupportedComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const componentHash = 1337;
+    const componentName = 'topkek';
+    const componentVersion = 1;
+    const componentData = '11110111001100010000' as BinaryString;
+
+    const component = new UnsupportedComponent({
+      hash: componentHash,
+      name: componentName,
+      version: componentVersion,
+      rawData: componentData
+    });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData = '000000000000000000000101001110010000000000000000000000000001010011110111001100010000';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    const dataLength = reader.readUnsignedInteger();
+    const rawData = reader.readBits(dataLength);
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(rawData).toStrictEqual(componentData);
+  });
+});
diff --git a/src/components/UnsupportedComponent.ts b/src/components/UnsupportedComponent.ts
new file mode 100644
index 0000000..da95e1e
--- /dev/null
+++ b/src/components/UnsupportedComponent.ts
@@ -0,0 +1,92 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+export type UnsupportedComponentProps = {
+  hash: number;
+  name: string;
+  rawData: BinaryString;
+};
+
+/**
+ * A component whose data shape has not been configured in _ATT String Transcoder_. Its internal
+ * data shape is a raw binary data string so it may be re-encoded later.
+ *
+ * @see [Class: `UnsupportedComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/UnsupportedComponent.md)
+ * @since v3.0.0
+ *
+ * @example
+ * import { UnsupportedComponent, type BinaryString } from 'att-string-transcoder';
+ *
+ * const hash = 1337;
+ * const name = 'SomeUnrecognisedComponentName';
+ * const rawData = '11110111001100010000' as BinaryString;
+ * const version = 1;
+ *
+ * const component = new UnsupportedComponent({ hash, name, rawData, version });
+ */
+export class UnsupportedComponent extends Component {
+  /**
+   * The component's serialised data.
+   *
+   * @example
+   * import { UnsupportedComponent } from 'att-string-transcoder';
+   *
+   * const hash = 1337;
+   * const name = 'SomeUnrecognisedComponentName';
+   * const rawData = '11110111001100010000';
+   * const version = 1;
+   *
+   * const component = new UnsupportedComponent({ hash, name, rawData, version });
+   *
+   * const rawData = component.rawData;
+   * // `rawData` is `'11110111001100010000'`
+   */
+  rawData: BinaryString;
+
+  /**
+   * Creates a versioned component without deserialising its data.
+   *
+   * @see [Class: `UnsupportedComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/UnsupportedComponent.md)
+   * @since v3.0.0
+   *
+   * @example
+   * import { UnsupportedComponent, type BinaryString } from 'att-string-transcoder';
+   *
+   * const hash = 1337;
+   * const name = 'SomeUnrecognisedComponentName';
+   * const rawData = '11110111001100010000' as BinaryString;
+   * const version = 1;
+   *
+   * const component = new UnsupportedComponent({ hash, name, rawData, version });
+   */
+  constructor({ hash, name, rawData, version }: ComponentProps & UnsupportedComponentProps) {
+    super({ hash, name, version });
+
+    this.rawData = rawData;
+  }
+
+  static override fromBinary(
+    reader: BinaryReader,
+    version: number,
+    hash: number,
+    name: string,
+    dataLength: number
+  ): UnsupportedComponent {
+    return new UnsupportedComponent({
+      hash,
+      name,
+      version,
+      rawData: reader.readBits(dataLength)
+    });
+  }
+
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  override toBinary(_ = this.version): BinaryString {
+    /**
+     * @property {BinaryString} rawData
+     */
+    return this.rawData;
+  }
+}
diff --git a/src/components/WoodcutTreeComponent.test.ts b/src/components/WoodcutTreeComponent.test.ts
new file mode 100644
index 0000000..6a5bbbc
--- /dev/null
+++ b/src/components/WoodcutTreeComponent.test.ts
@@ -0,0 +1,132 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { SpeciesHash } from '../types/SpeciesHash.js';
+
+import { WoodcutTreeComponent } from './WoodcutTreeComponent.js';
+
+const componentHash = ComponentHash.WoodcutTree;
+const componentName = 'WoodcutTree';
+const componentVersion = 3;
+const componentProps = {
+  presetHash: 0,
+  speciesHash: SpeciesHash.Walnut
+};
+
+describe('new WoodcutTreeComponent()', () => {
+  describe('when given the required props', () => {
+    it('returns an instance of the WoodcutTreeComponent class', () => {
+      const component = new WoodcutTreeComponent({ version: componentVersion });
+
+      expect(component).toBeInstanceOf(WoodcutTreeComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+    });
+  });
+
+  describe('when given additional props', () => {
+    it('returns an instance of the WoodcutTreeComponent class', () => {
+      const component = new WoodcutTreeComponent({ version: componentVersion, ...componentProps });
+
+      expect(component).toBeInstanceOf(WoodcutTreeComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect(component.version).toStrictEqual(componentVersion);
+      expect(component.presetHash).toStrictEqual(componentProps.presetHash);
+      expect(component.speciesHash).toStrictEqual(componentProps.speciesHash);
+    });
+  });
+});
+
+describe('WoodcutTreeComponent.fromBinary()', () => {
+  let fastForwardedReader: BinaryReader;
+
+  const prefab = new Prefab('Grass_Clump', {
+    components: {
+      WoodcutTree: new WoodcutTreeComponent({ version: componentVersion, ...componentProps })
+    }
+  });
+
+  beforeEach(() => {
+    const saveString = prefab.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // WoodcutTreeComponent hash.
+    reader.readUnsignedInteger(); // WoodcutTreeComponent data length.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns an instance of the WoodcutTreeComponent class', () => {
+    const component = WoodcutTreeComponent.fromBinary(fastForwardedReader, componentVersion);
+
+    expect(component).toBeInstanceOf(WoodcutTreeComponent);
+    expect(component.hash).toStrictEqual(componentHash);
+    expect(component.name).toStrictEqual(componentName);
+    expect(component.version).toStrictEqual(componentVersion);
+    expect(component.presetHash).toStrictEqual(componentProps.presetHash);
+    expect(component.speciesHash).toStrictEqual(componentProps.speciesHash);
+  });
+});
+
+describe('WoodcutTreeComponent.toBinary()', () => {
+  it('returns a BinaryString representation of the component', () => {
+    const component = new WoodcutTreeComponent({ version: componentVersion, ...componentProps });
+
+    const data = component.toBinary();
+
+    const expectedData = '0000000000000000000000000000000000000000000000000110110110001100';
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
+
+describe('WoodcutTreeComponent.write()', () => {
+  it('writes a BinaryString representation of the component to the given BinaryWriter, including component hash and data length', () => {
+    const component = new WoodcutTreeComponent({ version: componentVersion, ...componentProps });
+
+    const writer = new BinaryWriter();
+    component.write(writer);
+
+    const data = writer.flush();
+
+    const expectedData =
+      '01000001011100101110101010001111000000000000000000000000010000000000000000000000000000000000000000000000000000000110110110001100';
+
+    expect(data).toStrictEqual(expectedData);
+
+    const reader = new BinaryReader(data);
+
+    const hash = reader.readUnsignedInteger();
+    reader.readUnsignedInteger(); // WoodcutTreeComponent data length.
+    const presetHash = reader.readUnsignedInteger();
+    const speciesHash = reader.readUnsignedInteger();
+
+    expect(hash).toStrictEqual(componentHash);
+    expect(presetHash).toStrictEqual(componentProps.presetHash);
+    expect(speciesHash).toStrictEqual(componentProps.speciesHash);
+  });
+});
diff --git a/src/components/WoodcutTreeComponent.ts b/src/components/WoodcutTreeComponent.ts
new file mode 100644
index 0000000..ceaac05
--- /dev/null
+++ b/src/components/WoodcutTreeComponent.ts
@@ -0,0 +1,129 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { BinaryString } from '../types/BinaryString.js';
+import type { PresetHash } from '../types/PresetHash.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+import { SpeciesHash } from '../types/SpeciesHash.js';
+
+import { Component, type ComponentProps } from './Component.js';
+
+type WoodcutTreeComponentPropsV3 = {
+  presetHash?: 0 | PresetHash | undefined;
+  speciesHash?: SpeciesHash | undefined;
+};
+
+export type WoodcutTreeComponentProps = WoodcutTreeComponentPropsV3;
+
+/**
+ * @see [Class: `WoodcutTreeComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/WoodcutTreeComponent.md)
+ * @since v3.0.0
+ * @version 3
+ *
+ * @example
+ * import { WoodcutTreeComponent } from 'att-string-transcoder';
+ *
+ * const componentVersion = 3;
+ * const component = new WoodcutTreeComponent({ version: componentVersion });
+ */
+export class WoodcutTreeComponent extends Component {
+  /**
+   * @since v3
+   *
+   * @example
+   * import { WoodcutTreeComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 3;
+   * const component = new WoodcutTreeComponent({ version: componentVersion });
+   *
+   * const presetHash = component.presetHash;
+   * // `presetHash` is `0`
+   */
+  presetHash: 0 | PresetHash;
+
+  /**
+   * The hash of the species of the tree prefab this component is attached to.
+   *
+   * @since v3
+   *
+   * @example
+   * import { WoodcutTreeComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 3;
+   * const component = new WoodcutTreeComponent({ version: componentVersion });
+   *
+   * const speciesHash = component.speciesHash;
+   * // `speciesHash` is `11232`
+   */
+  speciesHash: SpeciesHash;
+
+  /**
+   * @see [Class: `WoodcutTreeComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/WoodcutTreeComponent.md)
+   * @since v3.0.0
+   * @version 3
+   *
+   * @example
+   * import { WoodcutTreeComponent } from 'att-string-transcoder';
+   *
+   * const componentVersion = 3;
+   * const component = new WoodcutTreeComponent({ version: componentVersion });
+   */
+  constructor({ version, presetHash, speciesHash }: ComponentProps & WoodcutTreeComponentProps) {
+    const hash = ComponentHash.WoodcutTree;
+    const name = 'WoodcutTree';
+
+    super({ hash, name, version });
+
+    this.presetHash = presetHash ?? 0;
+    this.speciesHash = speciesHash ?? SpeciesHash.Oak;
+  }
+
+  static override fromBinary(reader: BinaryReader, version: number): WoodcutTreeComponent {
+    const props: ComponentProps & WoodcutTreeComponentProps = { version };
+
+    /**
+     * @property {number} presetHash
+     * @since v3
+     */
+    if (props.version >= 3) {
+      props.presetHash = reader.readUnsignedInteger();
+    }
+
+    /**
+     * @property {number} speciesHash
+     * @since v3
+     */
+    if (props.version >= 3) {
+      props.speciesHash = reader.readUnsignedInteger();
+    }
+
+    return new WoodcutTreeComponent(props);
+  }
+
+  override toBinary(version = this.version): BinaryString {
+    const writer = new BinaryWriter();
+
+    /**
+     * @property {number} presetHash
+     * @since v3
+     */
+
+    /**
+     * @property {number} presetHash
+     * @since v3
+     */
+    if (version >= 3) {
+      writer.writeUnsignedInteger(this.presetHash);
+    }
+
+    /**
+     * @property {number} speciesHash
+     * @since v3
+     */
+    if (version >= 3) {
+      writer.writeUnsignedInteger(this.speciesHash);
+    }
+
+    return writer.flush();
+  }
+}
diff --git a/src/components/index.ts b/src/components/index.ts
deleted file mode 100644
index a11b62d..0000000
--- a/src/components/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as transcoders from './transcoders';
-
-export { ComponentVersion } from './ComponentVersion';
-
-export type ComponentName = keyof typeof transcoders;
-
-export type KnownComponent =
-  | transcoders.BasicDecay.Component
-  | transcoders.DurabilityModule.Component
-  | transcoders.HeatSourceBase.Component
-  | transcoders.LiquidContainer.Component
-  | transcoders.NetworkRigidbody.Component
-  | transcoders.PhysicalMaterialPart.Component
-  | transcoders.Pickup.Component
-  | transcoders.PickupDock.Component
-  | transcoders.PopulationSpawnArea.Component
-  | transcoders.SpawnArea.Component
-  | transcoders.StatManager.Component
-  | transcoders.WoodcutTree.Component;
-
-export type UnknownComponent = { hash: number; data: string };
-
-export type Component = KnownComponent | UnknownComponent[];
-
-export { transcoders };
diff --git a/src/components/transcoders/basicDecay.ts b/src/components/transcoders/basicDecay.ts
deleted file mode 100644
index 19239da..0000000
--- a/src/components/transcoders/basicDecay.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.BasicDecay;
-export const VERSION = 3;
-
-const HUNDRED_YEARS_TICKS = 31557600000000000;
-
-export type Component = {
-  isDisabled?: boolean;
-  timelineEntry?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  isDisabled: reader.boolean(),
-  timelineEntry: reader.uLong()
-});
-
-export const encode = ({ isDisabled = true, timelineEntry = HUNDRED_YEARS_TICKS }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.BasicDecay);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.boolean(isDisabled);
-  writer.uLong(timelineEntry);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/durabilityModule.ts b/src/components/transcoders/durabilityModule.ts
deleted file mode 100644
index 996a534..0000000
--- a/src/components/transcoders/durabilityModule.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.DurabilityModule;
-export const VERSION = 1;
-
-export type Component = {
-  integrity?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  integrity: reader.float()
-});
-
-export const encode = ({ integrity = 1 }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.DurabilityModule);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.float(integrity);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/heatSourceBase.ts b/src/components/transcoders/heatSourceBase.ts
deleted file mode 100644
index 3a61f2f..0000000
--- a/src/components/transcoders/heatSourceBase.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.HeatSourceBase;
-export const VERSION = 2;
-
-const HUNDRED_YEARS_TICKS = 31557600000000000;
-
-export type Component = {
-  isLit?: boolean;
-  progress?: number;
-  time?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  isLit: reader.boolean(),
-  progress: reader.float(),
-  time: reader.uLong()
-});
-
-export const encode = ({ isLit = true, progress = 0, time = HUNDRED_YEARS_TICKS }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.HeatSourceBase);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.boolean(isLit);
-  writer.float(progress);
-  writer.uLong(time);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/index.ts b/src/components/transcoders/index.ts
deleted file mode 100644
index 852ad90..0000000
--- a/src/components/transcoders/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export * as BasicDecay from './basicDecay';
-export * as DurabilityModule from './durabilityModule';
-export * as HeatSourceBase from './heatSourceBase';
-export * as LiquidContainer from './liquidContainer';
-export * as NetworkRigidbody from './networkRigidbody';
-export * as PhysicalMaterialPart from './physicalMaterialPart';
-export * as Pickup from './pickup';
-export * as PickupDock from './pickupDock';
-export * as PopulationSpawnArea from './populationSpawnArea';
-export * as SpawnArea from './spawnArea';
-export * as StatManager from './statManager';
-export * as WoodcutTree from './woodcutTree';
diff --git a/src/components/transcoders/liquidContainer.ts b/src/components/transcoders/liquidContainer.ts
deleted file mode 100644
index d0c2adc..0000000
--- a/src/components/transcoders/liquidContainer.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.LiquidContainer;
-export const VERSION = 1;
-
-type Color = {
-  r: number;
-  g: number;
-  b: number;
-  a: number;
-};
-
-type Effect = null | {
-  hash: number;
-  strengthMultiplier: number;
-};
-
-type FoodChunk = number;
-
-type CustomData = {
-  color: Color;
-  isConsumableThroughSkin: boolean;
-  visualDataHash: number;
-  effects: Effect[];
-  foodChunks: FoodChunk[];
-};
-
-export type Component = {
-  canAddTo?: boolean;
-  canRemoveFrom?: boolean;
-  contentLevel?: number;
-  hasContent?: boolean;
-  isCustom?: boolean;
-  presetHash?: number;
-  customData?: null | CustomData;
-};
-
-export const decode = (reader: BinaryReader): Component => {
-  const result: Component = {
-    canAddTo: reader.boolean(),
-    canRemoveFrom: reader.boolean(),
-    contentLevel: reader.int(),
-    hasContent: reader.boolean(),
-    isCustom: reader.boolean(),
-    presetHash: reader.uInt()
-  };
-
-  /* Get custom data */
-  const isNull = reader.boolean();
-  if (isNull) {
-    result.customData = null;
-  } else {
-    const customData = {
-      color: {
-        r: reader.float(),
-        g: reader.float(),
-        b: reader.float(),
-        a: reader.float()
-      },
-      isConsumableThroughSkin: reader.boolean(),
-      visualDataHash: reader.uInt()
-    };
-
-    /* Get the effects array. */
-    const effectsLength = reader.uInt();
-    const effects: Effect[] = [];
-    for (let index = 0; index < effectsLength; ++index) {
-      /* Skip effect if is null. */
-      const isNull = reader.boolean();
-      if (isNull) {
-        effects.push(null);
-        continue;
-      }
-
-      effects.push({
-        hash: reader.uInt(),
-        strengthMultiplier: reader.float()
-      });
-    }
-
-    /* Get the food chunks array. */
-    const foodChunksLength = reader.uInt();
-    const foodChunks: FoodChunk[] = [];
-    for (let index = 0; index < foodChunksLength; ++index) {
-      foodChunks.push(reader.uInt());
-    }
-
-    /* Append custom data to result. */
-    result.customData = {
-      ...customData,
-      effects,
-      foodChunks
-    };
-  }
-
-  return result;
-};
-
-export const encode = ({
-  canAddTo = false,
-  canRemoveFrom = false,
-  contentLevel = 0,
-  hasContent = !!contentLevel,
-  isCustom = false,
-  presetHash = 0,
-  customData = null
-}: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.LiquidContainer);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.boolean(canAddTo);
-  writer.boolean(canRemoveFrom);
-  writer.int(Math.round(contentLevel));
-  writer.boolean(hasContent);
-  writer.boolean(isCustom);
-  writer.uInt(presetHash);
-
-  if (customData === null) {
-    writer.boolean(true); // isNull bit
-  } else {
-    writer.boolean(false); // isNull bit
-    writer.float(customData.color.r);
-    writer.float(customData.color.g);
-    writer.float(customData.color.b);
-    writer.float(customData.color.a);
-    writer.boolean(customData.isConsumableThroughSkin);
-    writer.uInt(customData.visualDataHash);
-    writer.uInt(customData.effects.length);
-
-    for (const effect of customData.effects) {
-      if (effect === null) {
-        writer.boolean(true); // isNull bit
-      } else {
-        writer.boolean(false); // isNull bit
-        writer.uInt(effect.hash);
-        writer.float(effect.strengthMultiplier);
-      }
-    }
-
-    writer.uInt(customData.foodChunks.length);
-
-    for (const foodChunk of customData.foodChunks) {
-      writer.uInt(foodChunk);
-    }
-  }
-
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/networkRigidbody.ts b/src/components/transcoders/networkRigidbody.ts
deleted file mode 100644
index 76582cd..0000000
--- a/src/components/transcoders/networkRigidbody.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.NetworkRigidbody;
-export const VERSION = 1;
-
-export type Component = {
-  position?: {
-    x: number;
-    y: number;
-    z: number;
-  };
-  rotation?: {
-    x: number;
-    y: number;
-    z: number;
-    w: number;
-  };
-  isKinematic?: boolean;
-  isServerSleeping?: boolean;
-  velocity?: {
-    x: number;
-    y: number;
-    z: number;
-  };
-  angularVelocity?: {
-    x: number;
-    y: number;
-    z: number;
-  };
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  position: {
-    x: reader.float(),
-    y: reader.float(),
-    z: reader.float()
-  },
-  rotation: {
-    x: reader.float(),
-    y: reader.float(),
-    z: reader.float(),
-    w: reader.float()
-  },
-  isKinematic: reader.boolean(),
-  isServerSleeping: reader.boolean(),
-  velocity: {
-    x: reader.float(),
-    y: reader.float(),
-    z: reader.float()
-  },
-  angularVelocity: {
-    x: reader.float(),
-    y: reader.float(),
-    z: reader.float()
-  }
-});
-
-export const encode = ({
-  position = { x: 0, y: 0, z: 0 },
-  rotation = { x: 0, y: 0, z: 0, w: 1 },
-  isKinematic = false,
-  isServerSleeping = false,
-  velocity = { x: 0, y: 0, z: 0 },
-  angularVelocity = { x: 0, y: 0, z: 0 }
-}: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.NetworkRigidbody);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.float(position.x);
-  writer.float(position.y);
-  writer.float(position.z);
-  writer.float(rotation.x);
-  writer.float(rotation.y);
-  writer.float(rotation.z);
-  writer.float(rotation.w);
-  writer.boolean(isKinematic);
-  writer.boolean(isServerSleeping);
-  writer.float(velocity.x);
-  writer.float(velocity.y);
-  writer.float(velocity.z);
-  writer.float(angularVelocity.x);
-  writer.float(angularVelocity.y);
-  writer.float(angularVelocity.z);
-
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/physicalMaterialPart.ts b/src/components/transcoders/physicalMaterialPart.ts
deleted file mode 100644
index b6eeb6b..0000000
--- a/src/components/transcoders/physicalMaterialPart.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { PhysicalMaterialPartHash } from '../../PhysicalMaterialPartHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.PhysicalMaterialPart;
-export const VERSION = 1;
-
-export type Component = {
-  materialHash?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  materialHash: reader.uInt()
-});
-
-export const encode = ({ materialHash = PhysicalMaterialPartHash.Iron }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.PhysicalMaterialPart);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.uInt(materialHash);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/pickup.ts b/src/components/transcoders/pickup.ts
deleted file mode 100644
index c35fb51..0000000
--- a/src/components/transcoders/pickup.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.Pickup;
-export const VERSION = 1;
-
-export type Component = {
-  lastInteractorPlayerId?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  lastInteractorPlayerId: reader.int()
-});
-
-export const encode = ({ lastInteractorPlayerId = 0 }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.Pickup);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.int(lastInteractorPlayerId);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/pickupDock.ts b/src/components/transcoders/pickupDock.ts
deleted file mode 100644
index 98335c7..0000000
--- a/src/components/transcoders/pickupDock.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.PickupDock;
-export const VERSION = 2;
-
-export type Component = {
-  dockedTypeHash?: number;
-  quantity?: number;
-  childIndex?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  dockedTypeHash: reader.uInt(),
-  quantity: reader.int(),
-  childIndex: reader.int()
-});
-
-export const encode = ({ dockedTypeHash = 0, quantity = 1, childIndex = 0 }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.PickupDock);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.uInt(dockedTypeHash);
-  writer.int(quantity);
-  writer.int(childIndex);
-
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/populationSpawnArea.ts b/src/components/transcoders/populationSpawnArea.ts
deleted file mode 100644
index 8577c9a..0000000
--- a/src/components/transcoders/populationSpawnArea.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { PopulationDefinitionHash } from '../../PopulationDefinitionHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.PopulationSpawnArea;
-export const VERSION = 2;
-
-type PopulationSaveDataChild = {
-  index: number;
-  pointIndex: number;
-};
-
-export type Component = {
-  definition?: number;
-  isPopulationStarted?: boolean;
-  children?: PopulationSaveDataChild[];
-  maxPopulation?: number;
-  currentPopulation?: number;
-  checkPopulationTime?: number;
-  numberOfSpawnPoints?: number;
-  startingPopulation?: number;
-  isOneOff?: boolean;
-};
-
-export const decode = (reader: BinaryReader): Component => {
-  const definition = reader.uInt();
-  const isPopulationStarted = reader.boolean();
-
-  /* Get the children array. */
-  const childrenLength = reader.uInt();
-  const children: PopulationSaveDataChild[] = [];
-  for (let index = 0; index < childrenLength; ++index) {
-    children.push({
-      index: reader.int(),
-      pointIndex: reader.int()
-    });
-  }
-
-  const maxPopulation = reader.int();
-  const currentPopulation = reader.int();
-  const checkPopulationTime = reader.uLong();
-  const numberOfSpawnPoints = reader.int();
-  const startingPopulation = reader.int();
-  const isOneOff = reader.boolean();
-
-  return {
-    definition,
-    isPopulationStarted,
-    children,
-    maxPopulation,
-    currentPopulation,
-    checkPopulationTime,
-    numberOfSpawnPoints,
-    startingPopulation,
-    isOneOff
-  };
-};
-
-export const encode = ({
-  definition = PopulationDefinitionHash.StickPopulation,
-  isPopulationStarted = true,
-  children = [],
-  maxPopulation = 20,
-  currentPopulation = 5,
-  checkPopulationTime = 852974979330,
-  numberOfSpawnPoints = 40,
-  startingPopulation = 5,
-  isOneOff = false
-}: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.PopulationSpawnArea);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.uInt(definition);
-  writer.boolean(isPopulationStarted);
-  writer.uInt(children.length);
-
-  for (const child of children) {
-    if (child === null) {
-      writer.boolean(true); // isNull bit
-    } else {
-      writer.boolean(false); // isNull bit
-      writer.int(child.index);
-      writer.int(child.pointIndex);
-    }
-  }
-
-  writer.int(maxPopulation);
-  writer.int(currentPopulation);
-  writer.uLong(checkPopulationTime);
-  writer.int(numberOfSpawnPoints);
-  writer.int(startingPopulation);
-  writer.boolean(isOneOff);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/spawnArea.ts b/src/components/transcoders/spawnArea.ts
deleted file mode 100644
index d9cbeb7..0000000
--- a/src/components/transcoders/spawnArea.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.SpawnArea;
-export const VERSION = 1;
-
-export type Component = {
-  size?: number;
-  groundLayers?: number;
-  avoidLayers?: number;
-  isAligningNormal?: boolean;
-  maxAcceptableAngleDot?: number;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  size: reader.float(),
-  groundLayers: reader.int(),
-  avoidLayers: reader.int(),
-  isAligningNormal: reader.boolean(),
-  maxAcceptableAngleDot: reader.float()
-});
-
-export const encode = ({
-  size = 5,
-  groundLayers = 1280,
-  avoidLayers = 8721,
-  isAligningNormal = false,
-  maxAcceptableAngleDot = -1
-}: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.SpawnArea);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.float(size);
-  writer.int(groundLayers);
-  writer.int(avoidLayers);
-  writer.boolean(isAligningNormal);
-  writer.float(maxAcceptableAngleDot);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/statManager.ts b/src/components/transcoders/statManager.ts
deleted file mode 100644
index 3bf6ba8..0000000
--- a/src/components/transcoders/statManager.ts
+++ /dev/null
@@ -1,177 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.StatManager;
-export const VERSION = 2;
-
-type Stat = null | {
-  hash: number;
-  baseFlat: number;
-};
-
-type TimedModifier = null | {
-  hash: number;
-  value: number;
-  isMultiplier: boolean;
-  time: number;
-};
-
-type IndirectModifierSaveData = {
-  valueOverDurationHash: number;
-  baseValue: number;
-  duration: number;
-  tick: number;
-};
-
-type IndirectStatModifier = null | {
-  hash: number;
-  time: number;
-  modifiers: IndirectModifierSaveData[];
-};
-
-export type Component = {
-  stats?: Stat[];
-  modifiers?: TimedModifier[];
-  indirectStatModifiers?: IndirectStatModifier[];
-};
-
-export const decode = (reader: BinaryReader): Component => {
-  /* Get stats array. */
-  const statsLength = reader.uInt();
-  const stats: Stat[] = [];
-  for (let index = 0; index < statsLength; ++index) {
-    /* Skip stat if is null. */
-    const isNull = reader.boolean();
-    if (isNull) {
-      stats.push(null);
-      continue;
-    }
-
-    stats.push({
-      hash: reader.uInt(),
-      baseFlat: reader.float()
-    });
-  }
-
-  /* Get modifiers array. */
-  const modifiersLength = reader.uInt();
-  const modifiers: TimedModifier[] = [];
-  for (let index = 0; index < modifiersLength; ++index) {
-    /* Skip modifier if is null. */
-    const isNull = reader.boolean();
-    if (isNull) {
-      modifiers.push(null);
-      continue;
-    }
-
-    modifiers.push({
-      hash: reader.uInt(),
-      value: reader.float(),
-      isMultiplier: reader.boolean(),
-      time: reader.uLong()
-    });
-  }
-
-  /* Get indirect stat modifiers array. */
-  const indirectStatModifiersLength = reader.uInt();
-  const indirectStatModifiers: IndirectStatModifier[] = [];
-  for (let index = 0; index < indirectStatModifiersLength; ++index) {
-    /* Skip indirectStatModifier if is null. */
-    const isNull = reader.boolean();
-    if (isNull) {
-      indirectStatModifiers.push(null);
-      continue;
-    }
-
-    const hash = reader.uInt();
-    const time = reader.uLong();
-
-    /* Get indirect modifier save data array. */
-    const indirectModifiersSaveDataLength = reader.uInt();
-    const indirectModifiersSaveData: IndirectModifierSaveData[] = [];
-    for (let index = 0; index < indirectModifiersSaveDataLength; ++index) {
-      indirectModifiersSaveData.push({
-        valueOverDurationHash: reader.uInt(),
-        baseValue: reader.float(),
-        duration: reader.uInt(),
-        tick: reader.uInt()
-      });
-    }
-
-    indirectStatModifiers.push({
-      hash,
-      time,
-      modifiers: indirectModifiersSaveData
-    });
-  }
-
-  return { stats, modifiers, indirectStatModifiers };
-};
-
-export const encode = ({ stats = [], modifiers = [], indirectStatModifiers = [] }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.StatManager);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.uInt(stats.length);
-
-  for (const stat of stats) {
-    if (stat === null) {
-      writer.boolean(true); // isNull bit
-    } else {
-      writer.boolean(false); // isNull bit
-      writer.uInt(stat.hash);
-      writer.float(stat.baseFlat);
-    }
-  }
-
-  writer.uInt(modifiers.length);
-
-  for (const modifier of modifiers) {
-    if (modifier === null) {
-      writer.boolean(true); // isNull bit
-    } else {
-      writer.boolean(false); // isNull bit
-      writer.uInt(modifier.hash);
-      writer.float(modifier.value);
-      writer.boolean(modifier.isMultiplier);
-      writer.uLong(modifier.time);
-    }
-  }
-
-  writer.uInt(indirectStatModifiers.length);
-
-  for (const indirectStatModifier of indirectStatModifiers) {
-    if (indirectStatModifier === null) {
-      writer.boolean(true); // isNull bit
-    } else {
-      writer.boolean(false); // isNull bit
-      writer.uInt(indirectStatModifier.hash);
-      writer.uLong(indirectStatModifier.time);
-      writer.uInt(indirectStatModifier.modifiers.length);
-
-      for (const modifier of indirectStatModifier.modifiers) {
-        writer.uInt(modifier.valueOverDurationHash);
-        writer.float(modifier.baseValue);
-        writer.uInt(modifier.duration);
-        writer.uInt(modifier.tick);
-      }
-    }
-  }
-
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/components/transcoders/woodcutTree.ts b/src/components/transcoders/woodcutTree.ts
deleted file mode 100644
index bd234b0..0000000
--- a/src/components/transcoders/woodcutTree.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ComponentHash } from '../../ComponentHash';
-import { PresetHash } from '../../PresetHash';
-import { SpeciesHash } from '../../SpeciesHash';
-import { BinaryReader, createBinaryWriter } from '../../utils';
-
-export const HASH = ComponentHash.WoodcutTree;
-export const VERSION = 3;
-
-export type Component = {
-  presetHash?: 0 | PresetHash;
-  speciesHash?: SpeciesHash;
-};
-
-export const decode = (reader: BinaryReader): Component => ({
-  presetHash: reader.uInt(),
-  speciesHash: reader.uInt()
-});
-
-export const encode = ({ presetHash = 0, speciesHash = SpeciesHash.Oak }: Component): string => {
-  const writer = createBinaryWriter();
-
-  /* Component hash. */
-  writer.uInt(ComponentHash.WoodcutTree);
-  const hashBits = writer.flush();
-
-  /* Component data. */
-  writer.uInt(presetHash);
-  writer.uInt(speciesHash);
-  const dataBits = writer.flush();
-
-  /* Component data length. */
-  writer.uInt(dataBits.length);
-  const sizeBits = writer.flush();
-
-  /* Return encoded component. */
-  writer.binary(hashBits);
-  writer.binary(sizeBits);
-  writer.binary(dataBits);
-
-  return writer.flush();
-};
diff --git a/src/constants.ts b/src/constants.ts
new file mode 100644
index 0000000..d32374d
--- /dev/null
+++ b/src/constants.ts
@@ -0,0 +1,214 @@
+import type { ATTPrefabHash } from './types/ATTPrefabHash.js';
+import type { ATTPrefabName } from './types/ATTPrefabName.js';
+
+import { ATTPrefabs } from './types/ATTPrefabs.js';
+
+export const attPrefabHashes = Object.values(ATTPrefabs).map(({ hash }) => hash as number);
+
+export const attPrefabNames = Object.fromEntries<ATTPrefabName>(
+  Object.entries(ATTPrefabs).map(([name, { hash }]) => [hash, name as ATTPrefabName])
+) as Record<ATTPrefabHash, ATTPrefabName>;
+
+export const latestDurabilityModuleComponentVersion = 1;
+export const latestHeatSourceBaseComponentVersion = 1;
+export const latestLiquidContainerComponentVersion = 1;
+export const latestPhysicalMaterialPartComponentVersion = 1;
+export const latestPopulationSpawnAreaComponentVersion = 2;
+export const latestNetworkRigidbodyComponentVersion = 1;
+export const latestSentGiftComponentVersion = 1;
+export const latestSpawnAreaComponentVersion = 1;
+
+export const latestSupportedComponentVersions = new Map([
+  [7704646, 1], // PopulationPath
+  [22446553, 2], // Embeddable
+  [34507654, 1], // CylindricalBoundsSurface
+  [43510150, 2], // TaxManager
+  [70871065, 1], // SafePositionSetter
+  [109805019, 0], // WoodcutTree (duplicate with 1098050191)
+  [159391088, 1], // ModifiableAdditionalStaticContent
+  [200292695, 3], // LogicFloatChangeOnBool
+  [205333986, 1], // Cookable
+  [237360636, 2], // RopeGrab
+  [259381630, 1], // Ecosystem
+  [272188517, 1], // PhysicalMaterialPart
+  [276353327, 1], // WoodcutPointCollection
+  [277505782, 2], // Trigger
+  [309083880, 1], // AreaOfInfluenceReceiver
+  [320224849, 1], // WheelGrab
+  [391977879, 2], // Mould
+  [392234266, 3],
+  [392344172, 1], // LogicFloatThresholdReceiver
+  [403040752, 2], // PlayerDetect
+  [414036426, 0], // KeyItem
+  [496827038, 1],
+  [566175523, 1], // LinearPartCloner
+  [586602603, 1],
+  [623957243, 1],
+  [634164392, 5], // LootModule
+  [654225716, 1], // SpawnBuried
+  [661497638, 1], // SentGift
+  [701033518, 1],
+  [715394364, 2],
+  [751359624, 1], // GrowthStageComponent
+  [766675725, 1], // GenericCraftingStation
+  [775321715, 2],
+  [788405183, 1], // LevelStatModifier
+  [830106687, 1], // RespawnOnDestroy
+  [875684520, 1], // ForestGenerator
+  [902024186, 1], // Smelter
+  [910018632, 2], // GameTimeManager
+  [963907309, 1], // Book
+  [967932020, 1], // GlobalLogicManager
+  [986260983, 0], // PopulationFolder`2
+  [1001395212, 2], // PlaceItemPuzzleLogic
+  [1063725326, 1], // WayPointPath
+  [1081247904, 1], // LogicIntReceiver
+  [1085701614, 1], // TimeBasedStagedPrefab
+  [1098050191, 3], // WoodcutTree
+  [1176706580, 2], // PlaceItemNoDockPuzzleLogic
+  [1198377566, 1],
+  [1211178616, 1], // PlayerInteractionManager
+  [1217391130, 1], // HeatPointCollection
+  [1228539097, 1], // LogicVector3Receiver
+  [1233775263, 1], // PlayerProxy
+  [1257282635, 2], // LogicBoolSender
+  [1268269765, 1],
+  [1379877208, 0], // StewContainer
+  [1390862571, 1], // StageBasedPrefab
+  [1391720462, 2], // LogicGateReceiver
+  [1431397437, 2], // PopulationFolder
+  [1435171891, 0], // ImpactDetectionLogic
+  [1454441398, 2], // Pickup
+  [1454955908, 1], // SerializedFullEmptyStatTrigger
+  [1499506132, 1], // StewManager
+  [1509838052, 1], // FireLogic
+  [1556697998, 0], // MultiHandPickup
+  [1558189723, 1],
+  [1571096900, 0], // MouldRestrictor
+  [1587058252, 1], // LockableHinge
+  [1588536425, 1], // Crank
+  [1594932294, 0], // Lever
+  [1624211074, 1], // BasicDynamicPath
+  [1645673210, 2], // TradeVendor
+  [1651678475, 1], // RockCluster
+  [1714180166, 2], // SpawnInCircle
+  [1753993206, 2], // GlobalPagesManager
+  [1756836969, 1],
+  [1776498660, 3], // PositionRestrictor
+  [1787084913, 4], // CaveLayerManager
+  [1823429789, 1], // GhostSnapSlotCollection
+  [1871432223, 1], // DurabilityModule
+  [1874870249, 2], // MovePickup
+  [1908922854, 1], // AdditionalStaticContent
+  [1923918202, 3], // PageInstance
+  [1931537627, 1], // BasicPopulationFolder
+  [1934129787, 1], // LogicReset
+  [1946741389, 0], // PlayerLandmark
+  [1962842866, 1], // DirectionalBoundsSurface
+  [1964978567, 1], // LogicSumIntReceiver
+  [2026743731, 1], // LogicVector3Sender
+  [2042199192, 0], // TreeDecay
+  [2069630919, 1], // MRK_ActivationLever
+  [2081565440, 2],
+  [2120963769, 1], // LogicFloatSender
+  [2126500253, 1], // HealthBasedDigable
+  [2127962967, 1], // NetworkedFloatStream
+  [2169673426, 1], // MeshPlacement
+  [2190886200, 1], // SkillShrine
+  [2213531414, 0], // TwoStepLever
+  [2241532968, 0], // PaperPageInstance
+  [2253011220, 1], // LogicIntToBool
+  [2262399392, 2], // LeaderboardManager
+  [2272630171, 1], // ForgedPointCollection
+  [2290978823, 1], // NetworkRigidbody
+  [2293737711, 1], // OfflinePlayerProgressionHandler
+  [2314081177, 1], // LandmarkManager
+  [2363255897, 1],
+  [2400796504, 1], // SetPiece
+  [2443660852, 1], // MapBoard
+  [2450553269, 1], // Recycler
+  [2495475500, 2], // PlaceItemNoDockFirePuzzleLogic
+  [2498617949, 1], // RotatePickup
+  [2563434699, 1], // LogicIntThresholdReceiver
+  [2563567105, 2], // StatManager
+  [2576456808, 1], // CurveOutput
+  [2590537994, 2], // Landmark
+  [2592242915, 2], // PickupDock
+  [2610542999, 1], // LogicIntRangeReceiver
+  [2617495528, 1], // SpawnArea
+  [2624099526, 1], // Door
+  [2629079826, 1], // BookRestrictor
+  [2700376822, 1], // LogicFloatRangeReceiver
+  [2718386020, 0], // FireStatusRaycastCrafter
+  [2721336102, 0], // EnergyBasedHeatSource
+  [2743469720, 0], // PlayerStatManager
+  [2759613175, 1],
+  [2801168996, 2], // DrawBridgeRangeLogic
+  [2807522140, 0], // PickupDecay
+  [2814234626, 1], // LogicSumFloatReceiver
+  [2815374842, 1], // RaycastCrafter
+  [2833060406, 1],
+  [2880587164, 1], // LogicIntSender
+  [2882590463, 1], // CookingPot
+  [2912807649, 3], // PlayerUnlockStation
+  [2951515968, 1], // PlayerInteractionRestrictor
+  [2971871217, 1],
+  [2975913730, 1], // StaticGenerationParent
+  [2978042925, 1], // DrawBridgeLogic
+  [2978388169, 1], // PopulationDefinitionManager
+  [2978415408, 0], // GlobalLiquidContainer
+  [3008358716, 0], // DockableJoints
+  [3025846985, 0], // LevelSelectCaveTeleporter
+  [3070493599, 2], // PopulationSpawnArea
+  [3082855726, 0], // CapPickup
+  [3084373371, 1], // CommunalStorage
+  [3101665521, 1], // RandomSpawnRectangle
+  [3109677933, 2], // TimerLogic
+  [3146178080, 1], // TeleportationPoint
+  [3171294583, 1],
+  [3188272159, 1], // LogicFloatReceiver
+  [3202828999, 1],
+  [3230087383, 1], // OneTimeUpgradeuinteraction
+  [3236280681, 3], // ChisellingDeck
+  [3245685963, 1], // LogicFloatReset
+  [3257374625, 1], // Leaderboard
+  [3373651539, 1], // BuildupPickup
+  [3402094521, 1], // GrowerComponent
+  [3431876266, 1], // InfoBoard
+  [3445325106, 1], // DiggingImpactor
+  [3450348902, 1], // Visibility
+  [3457519710, 2], // Fire
+  [3538443740, 1], // PositionProvider
+  [3561515449, 1], // CaveLayerStreamer
+  [3583462804, 1], // SlidingDoor
+  [3588929783, 1], // CaveTeleporter
+  [3598052397, 0], // Chest
+  [3608460219, 1], // SerializedTimedEvent
+  [3638500874, 2], // TreeSpawner
+  [3640332570, 1], // CaveTeleporterManager
+  [3642863935, 2], // GeneratedLoot
+  [3665939353, 1], // Fuse
+  [3674519521, 1], // ModifiableStaticManager
+  [3684992773, 0], // ChildSyncableCollection`4
+  [3704379512, 1], // CheckPoint
+  [3715151601, 0], // GenerationStarter
+  [3751351177, 1], // LogicBoolReceiver
+  [3764204299, 0], // BookPageInstance
+  [3801256786, 3], // BasicDecay
+  [3810525047, 0], // LogicValueSender`1
+  [3820454400, 5], // RepairBox
+  [3884278372, 0], // MovingLandmark
+  [3901697682, 1], // ButtonCounter
+  [3920618075, 1], // ColoredExplosive
+  [3932346318, 1], // GlobalPopulationsManager
+  [4081488368, 1], // WipeManager
+  [4095875831, 1], // LandmarkDiscoverZone
+  [4109360768, 2], // HeatSourceBase
+  [4134534481, 1], // Enchantable
+  [4144776006, 3], // TimeManager
+  [4163873252, 0], // GlobalCommunalStorageValuesFile
+  [4179293747, 1], // LiquidContainer
+  [4282337604, 1] // SphericalSurface
+]);
+
+export const terminatorHash = 0;
diff --git a/src/createString.ts b/src/createString.ts
deleted file mode 100644
index f25ca3e..0000000
--- a/src/createString.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Prefab } from './decoders';
-import { binaryToUIntArray } from './utils';
-import { encodePrefab } from './encoders';
-import { getComponentVersions } from './getComponentVersions';
-
-export const createString = (prefab: Prefab): string => {
-  const hash = prefab.prefabObject.hash;
-
-  /* Encode the prefab. */
-  const binary = encodePrefab(prefab);
-
-  /* Pad bits with trailing zeroes to make it % 32. */
-  const missingBits = binary.length + (32 - (binary.length % 32 === 0 ? 32 : binary.length % 32));
-  const paddedBinary = binary.padEnd(missingBits, '0');
-
-  /* Calculate byte size of padded binary. */
-  const bytes = paddedBinary.length / 8;
-
-  /* Convert binary to array of UInts. */
-  const uInts = binaryToUIntArray(paddedBinary);
-
-  /* Construct the UInts string. */
-  const uIntString = [hash, bytes, ...uInts].join(',');
-
-  /* Construct the versions string. */
-  const versionString = getComponentVersions(prefab);
-
-  /* Return spawn string. */
-  const strings = [uIntString, versionString].filter(Boolean);
-  return `${strings.join(',|')},`;
-};
diff --git a/src/decodeString.ts b/src/decodeString.ts
deleted file mode 100644
index 4f98060..0000000
--- a/src/decodeString.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { uIntToBinary, createBinaryReader } from './utils';
-import { decodePrefab, Prefab } from './decoders';
-
-export type DecodedString = {
-  hash: number;
-  size: number;
-  prefab: Prefab;
-};
-
-/**
- * Break down a raw spawn string into:
- * - prefab object;
- * - components;
- * - child entities; and
- * - child prefabs.
- */
-export const decodeString = (rawString: string): DecodedString => {
-  /* Get the UInts portion of the raw spawn string. */
-  const uIntString = rawString.split('|')[0];
-  const uInts = uIntString.split(',').filter(Boolean);
-
-  /* Remove the first two UInts which do not count towards the string's size. */
-  const hash = Number(uInts.shift() ?? 0);
-  const size = 8 * Number(uInts.shift() ?? 0);
-
-  /* Convert remaining UInts to binary. */
-  const binary = uInts.reduce((bits, uInt) => `${bits}${uIntToBinary(Number(uInt))}`, '');
-
-  /* Create binary reader. */
-  const readBinary = createBinaryReader(binary);
-
-  const prefab = decodePrefab(readBinary);
-
-  return {
-    hash,
-    size,
-    prefab
-  };
-};
diff --git a/src/decoders/decodeChildPrefabs.ts b/src/decoders/decodeChildPrefabs.ts
deleted file mode 100644
index 5da5a0b..0000000
--- a/src/decoders/decodeChildPrefabs.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { BinaryReader } from '../utils';
-import { decodePrefab, Prefab } from './decodePrefab';
-
-export type ChildPrefab = {
-  parentHash: number;
-  prefab: Prefab;
-};
-
-export type ChildPrefabs = ChildPrefab[];
-
-export const decodeChildPrefabs = (reader: BinaryReader): ChildPrefab[] => {
-  const childPrefabs: ChildPrefab[] = [];
-
-  /* Continue looping until we find a false exists bit. */
-  while (true) {
-    /* Get the exists bit. */
-    const exists = reader.boolean();
-
-    /* Break if we reached the end of the child prefabs loop. */
-    if (!exists) break;
-
-    /* Get the parent entity hash. */
-    const parentHash = reader.uInt();
-
-    /* Get the child prefab. */
-    const prefab = decodePrefab(reader);
-
-    /* Save entity. */
-    childPrefabs.push({ parentHash, prefab });
-  }
-
-  return childPrefabs;
-};
diff --git a/src/decoders/decodeComponents.ts b/src/decoders/decodeComponents.ts
deleted file mode 100644
index c052c47..0000000
--- a/src/decoders/decodeComponents.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { transcoders, Component, ComponentName, UnknownComponent } from '../components';
-import { ComponentHash } from '../ComponentHash';
-import { BinaryReader } from '../utils';
-
-export type Components = {
-  [key in ComponentName | 'Unknown']?: Component;
-};
-
-export const decodeComponents = (reader: BinaryReader): Components => {
-  const components: Components = {
-    Unknown: []
-  };
-
-  /* Continue looping until we find a zero hash. */
-  while (true) {
-    /* Get the component hash. */
-    const hash = reader.uInt();
-
-    /* Break if we reached the end of the components loop. */
-    if (hash === 0) break;
-
-    /* Get the component's data length. */
-    const size = reader.uInt();
-
-    /* Get the component's name. */
-    const componentName = ComponentHash[hash] as ComponentName | undefined;
-
-    /* Save the component's data. */
-    if (componentName && transcoders[componentName]) {
-      components[componentName] = transcoders[componentName].decode(reader);
-    } else {
-      (components.Unknown as UnknownComponent[]).push({ hash, data: reader.binary(size) });
-    }
-  }
-
-  return components;
-};
diff --git a/src/decoders/decodeEmbeddedEntities.ts b/src/decoders/decodeEmbeddedEntities.ts
deleted file mode 100644
index b512922..0000000
--- a/src/decoders/decodeEmbeddedEntities.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { EmbeddedEntityHash } from '../EmbeddedEntityHash';
-import { BinaryReader } from '../utils';
-import { decodeComponents, Components } from './decodeComponents';
-import { Fire } from '../embeddedEntities';
-
-export type UnknownEmbeddedEntity = {
-  hash: number;
-  isAlive: boolean;
-  components: Components;
-};
-
-export type KnownEmbeddedEntity = Fire;
-
-export type EmbeddedEntities = {
-  Unknown?: UnknownEmbeddedEntity[];
-  Fire?: Fire;
-};
-
-export const decodeEmbeddedEntities = (reader: BinaryReader): EmbeddedEntities => {
-  const embeddedEntities: EmbeddedEntities = {
-    Unknown: []
-  };
-
-  /* Continue looping until we find a zero hash. */
-  while (true) {
-    /* Get the entity hash. */
-    const hash = reader.uInt();
-
-    /* Break if we reached the end of the entities loop. */
-    if (hash === 0) break;
-
-    /* Get entity name. */
-    const embeddedEntityName = (EmbeddedEntityHash[hash] ?? 'Unknown') as keyof EmbeddedEntities;
-
-    /* Read the entity's data length. */
-    reader.uInt();
-
-    /* Check if entity is still alive. */
-    const isAlive = reader.boolean();
-
-    /* Get the entity's components. */
-    const components = decodeComponents(reader);
-
-    /* Save entity. */
-    if (embeddedEntityName === 'Unknown') {
-      (embeddedEntities.Unknown as UnknownEmbeddedEntity[]).push({ hash, isAlive, components });
-    } else {
-      (embeddedEntities[embeddedEntityName] as KnownEmbeddedEntity) = { isAlive, components };
-    }
-  }
-
-  return embeddedEntities;
-};
diff --git a/src/decoders/decodePrefab.ts b/src/decoders/decodePrefab.ts
deleted file mode 100644
index 14aa2a1..0000000
--- a/src/decoders/decodePrefab.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { BinaryReader } from '../utils';
-import { decodePrefabObject, PrefabObject } from './decodePrefabObject';
-import { decodeComponents, Components } from './decodeComponents';
-import { decodeEmbeddedEntities, EmbeddedEntities } from './decodeEmbeddedEntities';
-import { decodeChildPrefabs, ChildPrefabs } from './decodeChildPrefabs';
-
-export type Prefab = {
-  prefabObject: PrefabObject;
-  components?: Components;
-  embeddedEntities?: EmbeddedEntities;
-  childPrefabs?: ChildPrefabs;
-};
-
-export const decodePrefab = (reader: BinaryReader): Prefab => {
-  const prefabObject = decodePrefabObject(reader);
-  const components = decodeComponents(reader);
-  const embeddedEntities = decodeEmbeddedEntities(reader);
-  const childPrefabs = decodeChildPrefabs(reader);
-
-  return {
-    prefabObject,
-    components,
-    embeddedEntities,
-    childPrefabs
-  };
-};
diff --git a/src/decoders/decodePrefabObject.ts b/src/decoders/decodePrefabObject.ts
deleted file mode 100644
index 3f8274f..0000000
--- a/src/decoders/decodePrefabObject.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { BinaryReader } from '../utils';
-
-export type PrefabObject = {
-  hash: number;
-  position?: {
-    x: number;
-    y: number;
-    z: number;
-  };
-  rotation?: {
-    x: number;
-    y: number;
-    z: number;
-    w: number;
-  };
-  scale?: number;
-};
-
-export const decodePrefabObject = (reader: BinaryReader): PrefabObject => ({
-  hash: reader.uInt(),
-  position: {
-    x: reader.float(),
-    y: reader.float(),
-    z: reader.float()
-  },
-  rotation: {
-    x: reader.float(),
-    y: reader.float(),
-    z: reader.float(),
-    w: reader.float()
-  },
-  scale: reader.float()
-});
diff --git a/src/decoders/index.ts b/src/decoders/index.ts
deleted file mode 100644
index 18a5f7d..0000000
--- a/src/decoders/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export { decodeComponents } from './decodeComponents';
-export { decodePrefab, Prefab } from './decodePrefab';
-export { PrefabObject } from './decodePrefabObject';
-export { Components } from './decodeComponents';
-export { EmbeddedEntities, KnownEmbeddedEntity, UnknownEmbeddedEntity } from './decodeEmbeddedEntities';
-export { ChildPrefab, ChildPrefabs } from './decodeChildPrefabs';
diff --git a/src/embeddedEntities/fire.ts b/src/embeddedEntities/fire.ts
deleted file mode 100644
index bf94539..0000000
--- a/src/embeddedEntities/fire.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Component } from '../components';
-
-export type Fire = {
-  isAlive?: boolean;
-  components?: {
-    Fire?: Component;
-    HeatSourceBase?: Component;
-    HeatSourcePointCollection?: Component;
-  };
-};
diff --git a/src/embeddedEntities/index.ts b/src/embeddedEntities/index.ts
deleted file mode 100644
index da2885c..0000000
--- a/src/embeddedEntities/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type { Fire } from './fire';
diff --git a/src/encoders/encodeChildPrefabs.ts b/src/encoders/encodeChildPrefabs.ts
deleted file mode 100644
index 94c0ad3..0000000
--- a/src/encoders/encodeChildPrefabs.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { ChildPrefabs } from '../decoders';
-import { createBinaryWriter } from '../utils/createBinaryWriter';
-import { encodePrefab } from '.';
-
-export const encodeChildPrefabs = (childPrefabs: ChildPrefabs = []): string => {
-  const writer = createBinaryWriter();
-
-  for (const childPrefab of childPrefabs) {
-    writer.boolean(true); // exists bit
-    writer.uInt(childPrefab.parentHash);
-
-    const childPrefabBits = encodePrefab(childPrefab.prefab);
-    writer.binary(childPrefabBits);
-  }
-
-  writer.boolean(false); // exists bit (terminator)
-
-  return writer.flush();
-};
diff --git a/src/encoders/encodeComponents.ts b/src/encoders/encodeComponents.ts
deleted file mode 100644
index 3e578b0..0000000
--- a/src/encoders/encodeComponents.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Components } from '../decoders';
-import { transcoders, KnownComponent, UnknownComponent, ComponentName } from '../components';
-import { createBinaryWriter } from '../utils/createBinaryWriter';
-
-const terminator = '0'.repeat(32);
-
-export const encodeComponents = (components: Components = {}): string => {
-  const writer = createBinaryWriter();
-
-  for (const [key, value] of Object.entries(components)) {
-    const componentName = key as ComponentName | 'Unknown';
-
-    if (componentName === 'Unknown') {
-      const unknownComponents = value as UnknownComponent[];
-
-      for (const { hash, data } of unknownComponents) {
-        writer.uInt(hash);
-        writer.uInt(data.length);
-        writer.binary(data);
-      }
-    } else {
-      try {
-        const knownComponent = value as KnownComponent;
-        const componentBits = transcoders[componentName].encode(knownComponent);
-        writer.binary(componentBits);
-      } catch (error) {
-        throw Error(`Cannot encode unsupported component '${componentName}'`);
-      }
-    }
-  }
-
-  const binary = writer.flush();
-
-  return `${binary}${terminator}`;
-};
diff --git a/src/encoders/encodeEmbeddedEntities.ts b/src/encoders/encodeEmbeddedEntities.ts
deleted file mode 100644
index f9ceb80..0000000
--- a/src/encoders/encodeEmbeddedEntities.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { EmbeddedEntities, KnownEmbeddedEntity, UnknownEmbeddedEntity } from '../decoders';
-import { EmbeddedEntityHash } from '../EmbeddedEntityHash';
-import { createBinaryWriter } from '../utils/createBinaryWriter';
-import { encodeComponents } from './encodeComponents';
-
-const terminator = '0'.repeat(32);
-
-export const encodeEmbeddedEntities = (entities: EmbeddedEntities = {}): string => {
-  const writer = createBinaryWriter();
-
-  for (const [key, value] of Object.entries(entities)) {
-    const embeddedEntityName = key as keyof EmbeddedEntities;
-
-    if (embeddedEntityName === 'Unknown') {
-      const unknownEmbeddedEntities = value as UnknownEmbeddedEntity[];
-
-      for (const { hash = 0, isAlive = true, components = {} } of unknownEmbeddedEntities) {
-        const componentsBits = encodeComponents(components);
-
-        writer.uInt(hash);
-        writer.uInt(1 + componentsBits.length);
-        writer.boolean(isAlive);
-        writer.binary(componentsBits);
-      }
-    } else {
-      const { isAlive = true, components = {} } = value as KnownEmbeddedEntity;
-      const componentsBits = encodeComponents(components);
-
-      writer.uInt(EmbeddedEntityHash[embeddedEntityName as keyof typeof EmbeddedEntityHash]);
-      writer.uInt(1 + componentsBits.length);
-      writer.boolean(isAlive);
-      writer.binary(componentsBits);
-    }
-  }
-
-  const binary = writer.flush();
-
-  return `${binary}${terminator}`;
-};
diff --git a/src/encoders/encodePrefab.ts b/src/encoders/encodePrefab.ts
deleted file mode 100644
index d0784bf..0000000
--- a/src/encoders/encodePrefab.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Prefab } from '../decoders';
-import { createBinaryWriter } from '../utils/createBinaryWriter';
-import { encodePrefabObject, encodeComponents, encodeEmbeddedEntities, encodeChildPrefabs } from '.';
-
-export const encodePrefab = (prefab: Prefab): string => {
-  const writer = createBinaryWriter();
-
-  /* Create prefab object. */
-  const prefabObjectBits = encodePrefabObject(prefab.prefabObject);
-  writer.binary(prefabObjectBits);
-
-  /* Create components. */
-  const componentsBits = encodeComponents(prefab.components);
-  writer.binary(componentsBits);
-
-  /* Create embedded entities. */
-  const embeddedEntitiesBits = encodeEmbeddedEntities(prefab.embeddedEntities);
-  writer.binary(embeddedEntitiesBits);
-
-  /* Create child prefabs. */
-  const childPrefabsBits = encodeChildPrefabs(prefab.childPrefabs);
-  writer.binary(childPrefabsBits);
-
-  return writer.flush();
-};
diff --git a/src/encoders/encodePrefabObject.ts b/src/encoders/encodePrefabObject.ts
deleted file mode 100644
index cfa2092..0000000
--- a/src/encoders/encodePrefabObject.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { PrefabObject } from '../decoders';
-import { createBinaryWriter } from '../utils';
-
-export const encodePrefabObject = ({
-  hash,
-  position = { x: 0, y: 0, z: 0 },
-  rotation = { x: 0, y: 0, z: 0, w: 1 },
-  scale = 1
-}: PrefabObject): string => {
-  const writer = createBinaryWriter();
-
-  /* Prefab object hash. */
-  writer.uInt(hash);
-
-  /* Prefab object data. */
-  writer.float(position.x);
-  writer.float(position.y);
-  writer.float(position.z);
-  writer.float(rotation.x);
-  writer.float(rotation.y);
-  writer.float(rotation.z);
-  writer.float(rotation.w);
-  writer.float(scale);
-
-  return writer.flush();
-};
diff --git a/src/encoders/index.ts b/src/encoders/index.ts
deleted file mode 100644
index 6e0e91f..0000000
--- a/src/encoders/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export { encodePrefab } from './encodePrefab';
-export { encodePrefabObject } from './encodePrefabObject';
-export { encodeComponents } from './encodeComponents';
-export { encodeEmbeddedEntities } from './encodeEmbeddedEntities';
-export { encodeChildPrefabs } from './encodeChildPrefabs';
diff --git a/src/getComponentVersions.ts b/src/getComponentVersions.ts
deleted file mode 100644
index c38fb0d..0000000
--- a/src/getComponentVersions.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { Components, KnownEmbeddedEntity, Prefab, UnknownEmbeddedEntity } from './decoders';
-import { ComponentName, UnknownComponent, ComponentVersion } from './components';
-import { ComponentHash } from './ComponentHash';
-
-type VersionPair = [number, number];
-
-const getComponentVersionPairs = (components: Components = {}) => {
-  const versionPairs: VersionPair[] = [];
-
-  for (const [key, value] of Object.entries(components)) {
-    const componentName = key as ComponentName | 'Unknown';
-
-    if (componentName === 'Unknown') {
-      const unknownComponents = value as UnknownComponent[];
-      versionPairs.push(
-        ...unknownComponents.map(
-          component => [component.hash, ComponentVersion.get(component.hash)] as [number, number]
-        )
-      );
-    } else {
-      const componentHash = ComponentHash[componentName];
-      const componentVersion = ComponentVersion.get(componentHash);
-      versionPairs.push([componentHash, componentVersion ?? 1]);
-    }
-  }
-
-  return versionPairs;
-};
-
-const getPrefabVersionPairs = (prefab: Prefab): VersionPair[] => {
-  const versionPairs: VersionPair[] = [];
-
-  if (prefab.components) {
-    versionPairs.push(...getComponentVersionPairs(prefab.components));
-  }
-
-  if (prefab.embeddedEntities) {
-    for (const [key, value] of Object.entries(prefab.embeddedEntities)) {
-      const embeddedEntityName = key as keyof KnownEmbeddedEntity | 'Unknown';
-
-      if (embeddedEntityName === 'Unknown') {
-        const unknownEmbeddedEntities = value as UnknownEmbeddedEntity[];
-
-        for (const embeddedEntity of unknownEmbeddedEntities) {
-          versionPairs.push(...getComponentVersionPairs(embeddedEntity.components));
-        }
-      } else {
-        const knownEmbeddedEntity = value as KnownEmbeddedEntity;
-
-        versionPairs.push(...getComponentVersionPairs(knownEmbeddedEntity.components));
-      }
-    }
-  }
-
-  if (prefab.childPrefabs?.length) {
-    for (const childPrefab of prefab.childPrefabs) {
-      versionPairs.push(...getPrefabVersionPairs(childPrefab.prefab));
-    }
-  }
-
-  return versionPairs;
-};
-
-export const getComponentVersions = (prefab: Prefab): string => {
-  const versionPairs = getPrefabVersionPairs(prefab);
-  const uniquePairs = versionPairs.filter(
-    ([hash], index) => versionPairs.findIndex(pair => pair[0] === hash) === index
-  );
-
-  const versions = uniquePairs.reduce((sum, [hash, version]) => `${sum},${hash},${version}`, '');
-
-  return `${uniquePairs.length}${versions}`;
-};
diff --git a/src/index.ts b/src/index.ts
index 7ee9be7..8ad1a7b 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,59 +1,110 @@
-/**
- * COMPONENTS
- */
-import * as components from './components/transcoders';
-export type BasicDecay = components.BasicDecay.Component;
-export type DurabilityModule = components.DurabilityModule.Component;
-export type HeatSourceBase = components.HeatSourceBase.Component;
-export type LiquidContainer = components.LiquidContainer.Component;
-export type NetworkRigidbody = components.NetworkRigidbody.Component;
-export type PhysicalMaterialPart = components.PhysicalMaterialPart.Component;
-export type Pickup = components.Pickup.Component;
-export type PickupDock = components.PickupDock.Component;
-export type PopulationSpawnArea = components.PopulationSpawnArea.Component;
-export type SpawnArea = components.SpawnArea.Component;
-export type StatManager = components.StatManager.Component;
-export type WoodcutTree = components.WoodcutTree.Component;
+/* Types */
+export type { BinaryDataOptions, UnpackFloatOptions } from './BinaryData.js';
+export type { EntityProps } from './Entity.js';
+export type { PrefabProps, ToSaveStringOptions } from './Prefab.js';
+export type { BasicDecayComponentProps } from './components/BasicDecayComponent.js';
+export type { ComponentProps } from './components/Component.js';
+export type { DurabilityModuleComponentProps } from './components/DurabilityModuleComponent.js';
+export type { FireComponentProps } from './components/FireComponent.js';
+export type { FuseComponentProps } from './components/FuseComponent.js';
+export type { HeatSourceBaseComponentProps } from './components/HeatSourceBaseComponent.js';
+export type { LiquidContainerComponentProps } from './components/LiquidContainerComponent.js';
+export type { LogicBoolReceiverComponentProps } from './components/LogicBoolReceiverComponent.js';
+export type { LogicBoolSenderComponentProps } from './components/LogicBoolSenderComponent.js';
+export type { LogicFloatReceiverComponentProps } from './components/LogicFloatReceiverComponent.js';
+export type { LogicFloatSenderComponentProps } from './components/LogicFloatSenderComponent.js';
+export type { LogicGateReceiverComponentProps } from './components/LogicGateReceiverComponent.js';
+export type { LogicIntReceiverComponentProps } from './components/LogicIntReceiverComponent.js';
+export type { LogicIntSenderComponentProps } from './components/LogicIntSenderComponent.js';
+export type { LogicVector3ReceiverComponentProps } from './components/LogicVector3ReceiverComponent.js';
+export type { LogicVector3SenderComponentProps } from './components/LogicVector3SenderComponent.js';
+export type { NetworkRigidbodyComponentProps } from './components/NetworkRigidbodyComponent.js';
+export type { PhysicalMaterialPartComponentProps } from './components/PhysicalMaterialPartComponent.js';
+export type { PickupComponentProps } from './components/PickupComponent.js';
+export type { PickupDockComponentProps } from './components/PickupDockComponent.js';
+export type { PopulationSpawnAreaComponentProps } from './components/PopulationSpawnAreaComponent.js';
+export type { SentGiftComponentProps } from './components/SentGiftComponent.js';
+export type { SpawnAreaComponentProps } from './components/SpawnAreaComponent.js';
+export type { StatManagerComponentProps } from './components/StatManagerComponent.js';
+export type { UnsupportedComponentProps } from './components/UnsupportedComponent.js';
+export type { WoodcutTreeComponentProps } from './components/WoodcutTreeComponent.js';
+export type { AngularVelocity } from './types/AngularVelocity.js';
+export type { ATTPrefabHash } from './types/ATTPrefabHash.js';
+export type { ATTPrefabName } from './types/ATTPrefabName.js';
+export type { BinaryString } from './types/BinaryString.js';
+export type { PopulationDefinitionName } from './types/PopulationDefinitionName.js';
+export type { Position } from './types/Position.js';
+export type { PrefabChild } from './types/PrefabChild.js';
+export type { PrefabComponents } from './types/PrefabComponents.js';
+export type { PrefabEntities } from './types/PrefabEntities.js';
+export type { Rotation } from './types/Rotation.js';
+export type { SaveString } from './types/SaveString.js';
+export type { SetSpawnAreaProps } from './types/SetSpawnAreaProps.js';
+export type { SupportedComponent } from './types/SupportedComponent.js';
+export type { SupportedPrefabComponents } from './types/SupportedPrefabComponents.js';
+export type { UnknownPrefabComponents } from './types/UnknownPrefabComponents.js';
+export type { UnsupportedPrefabComponents } from './types/UnsupportedPrefabComponents.js';
+export type { Velocity } from './types/Velocity.js';
 
-/**
- * EMBEDDED ENTITIES
- */
-export * from './embeddedEntities';
+/* Enums */
+export { ComponentHash } from './types/ComponentHash.js';
+export { LogicOperator } from './types/LogicOperator.js';
+export { PhysicalMaterialPartHash } from './types/PhysicalMaterialPartHash.js';
+export { PopulationDefinitionHash } from './types/PopulationDefinitionHash.js';
+export { PresetHash } from './types/PresetHash.js';
+export { SpeciesHash } from './types/SpeciesHash.js';
 
-/**
- * OBJECT SHAPES
- */
-export type { DecodedString } from './decodeString';
-export type {
-  Prefab,
-  PrefabObject,
-  Components,
-  EmbeddedEntities,
-  KnownEmbeddedEntity,
-  UnknownEmbeddedEntity,
-  ChildPrefab
-} from './decoders';
-export type { Component, KnownComponent, UnknownComponent } from './components';
+/* Binary classes */
+export { BinaryData } from './BinaryData.js';
+export { BinaryReader } from './BinaryReader.js';
+export { BinaryWriter } from './BinaryWriter.js';
 
-/**
- * HASHES
- */
-export { ComponentHash } from './ComponentHash';
-export { EmbeddedEntityHash } from './EmbeddedEntityHash';
-export { PhysicalMaterialPartHash } from './PhysicalMaterialPartHash';
-export { PopulationDefinitionHash } from './PopulationDefinitionHash';
-export { PrefabEmbeddedEntityHash } from './PrefabEmbeddedEntityHash';
-export { PrefabHash } from './PrefabHash';
-export { PresetHash } from './PresetHash';
-export { SpeciesHash } from './SpeciesHash';
+/* Prefabs */
+export { Prefab } from './Prefab.js';
+export { ATTPrefabs } from './types/ATTPrefabs.js';
 
-/**
- * UTILITIES
- */
-export * from './utils';
+/* Components */
+export { BasicDecayComponent } from './components/BasicDecayComponent.js';
+export { Component } from './components/Component.js';
+export { DoorComponent } from './components/DoorComponent.js';
+export { DurabilityModuleComponent } from './components/DurabilityModuleComponent.js';
+export { FireComponent } from './components/FireComponent.js';
+export { FuseComponent } from './components/FuseComponent.js';
+export { HeatSourceBaseComponent } from './components/HeatSourceBaseComponent.js';
+export { LiquidContainerComponent } from './components/LiquidContainerComponent.js';
+export { LogicBoolReceiverComponent } from './components/LogicBoolReceiverComponent.js';
+export { LogicBoolSenderComponent } from './components/LogicBoolSenderComponent.js';
+export { LogicFloatReceiverComponent } from './components/LogicFloatReceiverComponent.js';
+export { LogicFloatSenderComponent } from './components/LogicFloatSenderComponent.js';
+export { LogicGateReceiverComponent } from './components/LogicGateReceiverComponent.js';
+export { LogicIntReceiverComponent } from './components/LogicIntReceiverComponent.js';
+export { LogicIntSenderComponent } from './components/LogicIntSenderComponent.js';
+export { LogicVector3ReceiverComponent } from './components/LogicVector3ReceiverComponent.js';
+export { LogicVector3SenderComponent } from './components/LogicVector3SenderComponent.js';
+export { NetworkRigidbodyComponent } from './components/NetworkRigidbodyComponent.js';
+export { PhysicalMaterialPartComponent } from './components/PhysicalMaterialPartComponent.js';
+export { PickupComponent } from './components/PickupComponent.js';
+export { PickupDockComponent } from './components/PickupDockComponent.js';
+export { PopulationSpawnAreaComponent } from './components/PopulationSpawnAreaComponent.js';
+export { SentGiftComponent } from './components/SentGiftComponent.js';
+export { SlidingDoorComponent } from './components/SlidingDoorComponent.js';
+export { SpawnAreaComponent } from './components/SpawnAreaComponent.js';
+export { StatManagerComponent } from './components/StatManagerComponent.js';
+export { UnsupportedComponent } from './components/UnsupportedComponent.js';
+export { WoodcutTreeComponent } from './components/WoodcutTreeComponent.js';
 
-/**
- * ATT STRING TRANSCODER
- */
-export { createString } from './createString';
-export { decodeString } from './decodeString';
+/* Entities */
+export { Entity } from './Entity.js';
+
+/* Utilities */
+export { isATTPrefabHash } from './utils/isATTPrefabHash.js';
+export { isATTPrefabName } from './utils/isATTPrefabName.js';
+export { isSavableComponent } from './utils/isSavableComponent.js';
+export { isUnknownComponent } from './utils/isUnknownComponent.js';
+export { readChildren } from './utils/readChildren.js';
+export { readComponent } from './utils/readComponent.js';
+export { readComponents } from './utils/readComponents.js';
+export { readEntities } from './utils/readEntities.js';
+export { writeChildren } from './utils/writeChildren.js';
+export { writeComponents } from './utils/writeComponents.js';
+export { writeEntities } from './utils/writeEntities.js';
diff --git a/src/supportedComponents.ts b/src/supportedComponents.ts
new file mode 100644
index 0000000..67dcd48
--- /dev/null
+++ b/src/supportedComponents.ts
@@ -0,0 +1,57 @@
+import type { SupportedComponent } from './types/SupportedComponent.js';
+
+import { BasicDecayComponent } from './components/BasicDecayComponent.js';
+import { DoorComponent } from './components/DoorComponent.js';
+import { DurabilityModuleComponent } from './components/DurabilityModuleComponent.js';
+import { FireComponent } from './components/FireComponent.js';
+import { FuseComponent } from './components/FuseComponent.js';
+import { HeatSourceBaseComponent } from './components/HeatSourceBaseComponent.js';
+import { LiquidContainerComponent } from './components/LiquidContainerComponent.js';
+import { LogicBoolReceiverComponent } from './components/LogicBoolReceiverComponent.js';
+import { LogicBoolSenderComponent } from './components/LogicBoolSenderComponent.js';
+import { LogicFloatReceiverComponent } from './components/LogicFloatReceiverComponent.js';
+import { LogicFloatSenderComponent } from './components/LogicFloatSenderComponent.js';
+import { LogicGateReceiverComponent } from './components/LogicGateReceiverComponent.js';
+import { LogicIntReceiverComponent } from './components/LogicIntReceiverComponent.js';
+import { LogicIntSenderComponent } from './components/LogicIntSenderComponent.js';
+import { LogicVector3ReceiverComponent } from './components/LogicVector3ReceiverComponent.js';
+import { LogicVector3SenderComponent } from './components/LogicVector3SenderComponent.js';
+import { NetworkRigidbodyComponent } from './components/NetworkRigidbodyComponent.js';
+import { PhysicalMaterialPartComponent } from './components/PhysicalMaterialPartComponent.js';
+import { PickupComponent } from './components/PickupComponent.js';
+import { PickupDockComponent } from './components/PickupDockComponent.js';
+import { PopulationSpawnAreaComponent } from './components/PopulationSpawnAreaComponent.js';
+import { SentGiftComponent } from './components/SentGiftComponent.js';
+import { SlidingDoorComponent } from './components/SlidingDoorComponent.js';
+import { SpawnAreaComponent } from './components/SpawnAreaComponent.js';
+import { StatManagerComponent } from './components/StatManagerComponent.js';
+import { WoodcutTreeComponent } from './components/WoodcutTreeComponent.js';
+
+export const supportedComponents: Record<string, SupportedComponent> = {
+  BasicDecay: BasicDecayComponent,
+  Door: DoorComponent,
+  DurabilityModule: DurabilityModuleComponent,
+  Fire: FireComponent,
+  Fuse: FuseComponent,
+  HeatSourceBase: HeatSourceBaseComponent,
+  LiquidContainer: LiquidContainerComponent,
+  LogicBoolReceiver: LogicBoolReceiverComponent,
+  LogicBoolSender: LogicBoolSenderComponent,
+  LogicFloatReceiver: LogicFloatReceiverComponent,
+  LogicFloatSender: LogicFloatSenderComponent,
+  LogicGateReceiver: LogicGateReceiverComponent,
+  LogicIntReceiver: LogicIntReceiverComponent,
+  LogicIntSender: LogicIntSenderComponent,
+  LogicVector3Receiver: LogicVector3ReceiverComponent,
+  LogicVector3Sender: LogicVector3SenderComponent,
+  NetworkRigidbody: NetworkRigidbodyComponent,
+  PhysicalMaterialPart: PhysicalMaterialPartComponent,
+  Pickup: PickupComponent,
+  PickupDock: PickupDockComponent,
+  PopulationSpawnArea: PopulationSpawnAreaComponent,
+  SentGift: SentGiftComponent,
+  SlidingDoor: SlidingDoorComponent,
+  SpawnArea: SpawnAreaComponent,
+  StatManager: StatManagerComponent,
+  WoodcutTree: WoodcutTreeComponent
+};
diff --git a/src/types/ATTPrefabHash.ts b/src/types/ATTPrefabHash.ts
new file mode 100644
index 0000000..edc7799
--- /dev/null
+++ b/src/types/ATTPrefabHash.ts
@@ -0,0 +1,5 @@
+import type { ATTPrefabName } from './ATTPrefabName.js';
+
+import { ATTPrefabs } from './ATTPrefabs.js';
+
+export type ATTPrefabHash = (typeof ATTPrefabs)[ATTPrefabName]['hash'];
diff --git a/src/types/ATTPrefabName.ts b/src/types/ATTPrefabName.ts
new file mode 100644
index 0000000..556c867
--- /dev/null
+++ b/src/types/ATTPrefabName.ts
@@ -0,0 +1,3 @@
+import { ATTPrefabs } from './ATTPrefabs.js';
+
+export type ATTPrefabName = keyof typeof ATTPrefabs;
diff --git a/src/types/ATTPrefabs.ts b/src/types/ATTPrefabs.ts
new file mode 100644
index 0000000..83eb3b7
--- /dev/null
+++ b/src/types/ATTPrefabs.ts
@@ -0,0 +1,41507 @@
+/**
+ * Parsed spawn infodump.
+ * @since 2023-06-12
+ * @version 3.0.0
+ */
+export const ATTPrefabs = {
+  '(Child_Node)_Climbing_Tower_Teleporter_Node': {
+    'hash': 5078,
+    'name': '(Child_Node)_Climbing_Tower_Teleporter_Node',
+    'embedded': {
+      '(Child_Node)_Climbing_Tower_Teleporter_Node_56704': {
+        'hash': 56704,
+        'name': '(Child_Node)_Climbing_Tower_Teleporter_Node',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'ClimbingTowerTeleporterNode': {
+            'hash': 392234266,
+            'name': 'ClimbingTowerTeleporterNode'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Visualizer_56774': {
+        'hash': 56774,
+        'name': 'Visualizer',
+        'savables': {
+          'ClimbingTowerProgressionVisualizer': {
+            'hash': 623957243,
+            'name': 'ClimbingTowerProgressionVisualizer'
+          }
+        }
+      }
+    }
+  },
+  '(OriginalRoot_Node)_Climbing_Tower_Teleporter_Node': {
+    'hash': 55446,
+    'name': '(OriginalRoot_Node)_Climbing_Tower_Teleporter_Node',
+    'embedded': {
+      '(OriginalRoot_Node)_Climbing_Tower_Teleporter_Node_55438': {
+        'hash': 55438,
+        'name': '(OriginalRoot_Node)_Climbing_Tower_Teleporter_Node',
+        'savables': {
+          'ClimbingTowerTeleporterNode': {
+            'hash': 392234266,
+            'name': 'ClimbingTowerTeleporterNode'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  '(Original_Child_Node)_Climbing_Tower_Teleporter_Node': {
+    'hash': 26916,
+    'name': '(Original_Child_Node)_Climbing_Tower_Teleporter_Node',
+    'embedded': {
+      '(Original_Child_Node)_Climbing_Tower_Teleporter_Node_26908': {
+        'hash': 26908,
+        'name': '(Original_Child_Node)_Climbing_Tower_Teleporter_Node',
+        'savables': {
+          'ClimbingTowerTeleporterNode': {
+            'hash': 392234266,
+            'name': 'ClimbingTowerTeleporterNode'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  '(Root_Node)_Climbing_Tower_Teleporter_Node': {
+    'hash': 7668,
+    'name': '(Root_Node)_Climbing_Tower_Teleporter_Node',
+    'embedded': {
+      '(Root_Node)_Climbing_Tower_Teleporter_Node_56148': {
+        'hash': 56148,
+        'name': '(Root_Node)_Climbing_Tower_Teleporter_Node',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'ClimbingTowerTeleporterNode': {
+            'hash': 392234266,
+            'name': 'ClimbingTowerTeleporterNode'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Visualizer_56330': {
+        'hash': 56330,
+        'name': 'Visualizer',
+        'savables': {
+          'ClimbingTowerProgressionVisualizer': {
+            'hash': 623957243,
+            'name': 'ClimbingTowerProgressionVisualizer'
+          }
+        }
+      }
+    }
+  },
+  'ATM_Coin_Bank': {
+    'hash': 9780,
+    'name': 'ATM_Coin_Bank',
+    'embedded': {
+      'ATM_Coin_Bank_7202': {
+        'hash': 7202,
+        'name': 'ATM_Coin_Bank',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Base_Dock_28320': {
+        'hash': 28320,
+        'name': 'Base_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'DepositDock_33532': {
+        'hash': 33532,
+        'name': 'DepositDock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Grab_22452': {
+        'hash': 22452,
+        'name': 'Grab',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'Withdraw_Dock_34750': {
+        'hash': 34750,
+        'name': 'Withdraw_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Absolute_Apple_Tree_Variant': {
+    'hash': 15898,
+    'name': 'Absolute_Apple_Tree_Variant',
+    'embedded': {
+      'Absolute_Apple_Tree_Variant_58592': {
+        'hash': 58592,
+        'name': 'Absolute_Apple_Tree_Variant',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Absolute_Blueberry_Tree_Variant': {
+    'hash': 16322,
+    'name': 'Absolute_Blueberry_Tree_Variant',
+    'embedded': {
+      'Absolute_Blueberry_Tree_Variant_24412': {
+        'hash': 24412,
+        'name': 'Absolute_Blueberry_Tree_Variant',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'And': {
+    'hash': 42422,
+    'name': 'And',
+    'embedded': {}
+  },
+  'Anvil': {
+    'hash': 23182,
+    'name': 'Anvil',
+    'embedded': {
+      'Anvil_57386': {
+        'hash': 57386,
+        'name': 'Anvil',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Anvil_Training': {
+    'hash': 24218,
+    'name': 'Anvil_Training',
+    'embedded': {
+      'Anvil_Training_24216': {
+        'hash': 24216,
+        'name': 'Anvil_Training',
+        'savables': {}
+      }
+    }
+  },
+  'Apple_Core_Burnt': {
+    'hash': 50484,
+    'name': 'Apple_Core_Burnt',
+    'embedded': {
+      'Apple_Core_Burnt_10462': {
+        'hash': 10462,
+        'name': 'Apple_Core_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_5784': {
+        'hash': 5784,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Core_Cooked': {
+    'hash': 15500,
+    'name': 'Apple_Core_Cooked',
+    'embedded': {
+      'Apple_Core_Cooked_10462': {
+        'hash': 10462,
+        'name': 'Apple_Core_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_5784': {
+        'hash': 5784,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Core_Ripe': {
+    'hash': 902,
+    'name': 'Apple_Core_Ripe',
+    'embedded': {
+      'Apple_Core_Ripe_10462': {
+        'hash': 10462,
+        'name': 'Apple_Core_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_5784': {
+        'hash': 5784,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Core_Unripe': {
+    'hash': 31614,
+    'name': 'Apple_Core_Unripe',
+    'embedded': {
+      'Apple_Core_Unripe_10462': {
+        'hash': 10462,
+        'name': 'Apple_Core_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      },
+      'Cooking_5784': {
+        'hash': 5784,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Flower_Bloom': {
+    'hash': 12580,
+    'name': 'Apple_Flower_Bloom',
+    'embedded': {
+      'Apple_Flower_Bloom_29560': {
+        'hash': 29560,
+        'name': 'Apple_Flower_Bloom',
+        'savables': {}
+      }
+    }
+  },
+  'Apple_Flower_Bud': {
+    'hash': 12578,
+    'name': 'Apple_Flower_Bud',
+    'embedded': {
+      'Apple_Flower_Bud_35946': {
+        'hash': 35946,
+        'name': 'Apple_Flower_Bud',
+        'savables': {}
+      }
+    }
+  },
+  'Apple_Full_Burnt': {
+    'hash': 62102,
+    'name': 'Apple_Full_Burnt',
+    'embedded': {
+      'Apple_Core_Spawner_52298': {
+        'hash': 52298,
+        'name': 'Apple_Core_Spawner',
+        'savables': {}
+      },
+      'Apple_Full_Burnt_57036': {
+        'hash': 57036,
+        'name': 'Apple_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_11820': {
+        'hash': 11820,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Full_Cooked': {
+    'hash': 14844,
+    'name': 'Apple_Full_Cooked',
+    'embedded': {
+      'Apple_Core_Spawner_53358': {
+        'hash': 53358,
+        'name': 'Apple_Core_Spawner',
+        'savables': {}
+      },
+      'Apple_Full_Cooked_56646': {
+        'hash': 56646,
+        'name': 'Apple_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_5588': {
+        'hash': 5588,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Full_Ripe': {
+    'hash': 40010,
+    'name': 'Apple_Full_Ripe',
+    'embedded': {
+      'Apple_Core_Spawner_56836': {
+        'hash': 56836,
+        'name': 'Apple_Core_Spawner',
+        'savables': {}
+      },
+      'Apple_Full_Ripe_56174': {
+        'hash': 56174,
+        'name': 'Apple_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_2434': {
+        'hash': 2434,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Full_Unripe': {
+    'hash': 6740,
+    'name': 'Apple_Full_Unripe',
+    'embedded': {
+      'Apple_Core_Spawner_37092': {
+        'hash': 37092,
+        'name': 'Apple_Core_Spawner',
+        'savables': {}
+      },
+      'Apple_Full_Unripe_55618': {
+        'hash': 55618,
+        'name': 'Apple_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_430': {
+        'hash': 430,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Growth': {
+    'hash': 19192,
+    'name': 'Apple_Growth',
+    'embedded': {
+      'Apple_Growth_33458': {
+        'hash': 33458,
+        'name': 'Apple_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Half_Burnt': {
+    'hash': 65526,
+    'name': 'Apple_Half_Burnt',
+    'embedded': {
+      'Apple_Half_Burnt_55062': {
+        'hash': 55062,
+        'name': 'Apple_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_64844': {
+        'hash': 64844,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Half_Cooked': {
+    'hash': 2000,
+    'name': 'Apple_Half_Cooked',
+    'embedded': {
+      'Apple_Half_Cooked_54784': {
+        'hash': 54784,
+        'name': 'Apple_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_61738': {
+        'hash': 61738,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Half_Ripe': {
+    'hash': 7278,
+    'name': 'Apple_Half_Ripe',
+    'embedded': {
+      'Apple_Half_Ripe_54506': {
+        'hash': 54506,
+        'name': 'Apple_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_54586': {
+        'hash': 54586,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Half_Unripe': {
+    'hash': 62012,
+    'name': 'Apple_Half_Unripe',
+    'embedded': {
+      'Apple_Half_Unripe_54228': {
+        'hash': 54228,
+        'name': 'Apple_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_60662': {
+        'hash': 60662,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Tree': {
+    'hash': 61222,
+    'name': 'Apple_Tree',
+    'embedded': {
+      'Apple_Tree_58592': {
+        'hash': 58592,
+        'name': 'Apple_Tree',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Tree_Growth': {
+    'hash': 14226,
+    'name': 'Apple_Tree_Growth',
+    'embedded': {
+      'Apple_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Apple_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Tree_Separated': {
+    'hash': 8974,
+    'name': 'Apple_Tree_Separated',
+    'embedded': {}
+  },
+  'Apple_Tree_Stage_1': {
+    'hash': 50926,
+    'name': 'Apple_Tree_Stage_1',
+    'embedded': {
+      'Apple_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Apple_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Apple_Tree_Stage_2': {
+    'hash': 57538,
+    'name': 'Apple_Tree_Stage_2',
+    'embedded': {
+      'Apple_Tree_Stage_2_11646': {
+        'hash': 11646,
+        'name': 'Apple_Tree_Stage_2',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Apple_Tree_Stage_3': {
+    'hash': 62702,
+    'name': 'Apple_Tree_Stage_3',
+    'embedded': {
+      'Apple_Tree_Stage_3_15774': {
+        'hash': 15774,
+        'name': 'Apple_Tree_Stage_3',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Area_of_Influence_Receiver_puzzle': {
+    'hash': 13256,
+    'name': 'Area_of_Influence_Receiver_puzzle',
+    'embedded': {
+      'Area_of_Influence_Receiver_puzzle_13236': {
+        'hash': 13236,
+        'name': 'Area_of_Influence_Receiver_puzzle',
+        'savables': {
+          'AreaOfInfluenceReceiver': {
+            'hash': 309083880,
+            'name': 'AreaOfInfluenceReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  'Area_of_Influence_Sender_puzzle': {
+    'hash': 59482,
+    'name': 'Area_of_Influence_Sender_puzzle',
+    'embedded': {
+      'Area_of_Influence_Sender_puzzle_59428': {
+        'hash': 59428,
+        'name': 'Area_of_Influence_Sender_puzzle',
+        'savables': {
+          'AreaOfInfluenceSender': {
+            'hash': 176949352,
+            'name': 'AreaOfInfluenceSender'
+          },
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          }
+        }
+      }
+    }
+  },
+  'Arrow': {
+    'hash': 56460,
+    'name': 'Arrow',
+    'embedded': {
+      'Arrow_43746': {
+        'hash': 43746,
+        'name': 'Arrow',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Arrow_Tip_59378': {
+        'hash': 59378,
+        'name': 'Arrow_Tip',
+        'savables': {}
+      }
+    }
+  },
+  'Arrow_Light_Beam_Effect': {
+    'hash': 1798,
+    'name': 'Arrow_Light_Beam_Effect',
+    'embedded': {
+      'Arrow_Light_Beam_Effect_64504': {
+        'hash': 64504,
+        'name': 'Arrow_Light_Beam_Effect',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Arrow_Shaft_Wooden': {
+    'hash': 29772,
+    'name': 'Arrow_Shaft_Wooden',
+    'embedded': {
+      'Arrow_Shaft_Wooden_31664': {
+        'hash': 31664,
+        'name': 'Arrow_Shaft_Wooden',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Deco_33560': {
+        'hash': 33560,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Feather_38282': {
+        'hash': 38282,
+        'name': 'Slot_Feather',
+        'savables': {}
+      },
+      'Slot_Grass_13582': {
+        'hash': 13582,
+        'name': 'Slot_Grass',
+        'savables': {}
+      },
+      'Tip_59148': {
+        'hash': 59148,
+        'name': 'Tip',
+        'savables': {}
+      }
+    }
+  },
+  'Arrow_Shaft_Wooden_Training': {
+    'hash': 36772,
+    'name': 'Arrow_Shaft_Wooden_Training',
+    'embedded': {
+      'Arrow_Shaft_Wooden_Training_36760': {
+        'hash': 36760,
+        'name': 'Arrow_Shaft_Wooden_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Tip_59796': {
+        'hash': 59796,
+        'name': 'Tip',
+        'savables': {}
+      }
+    }
+  },
+  'Arrow_Training': {
+    'hash': 36190,
+    'name': 'Arrow_Training',
+    'embedded': {
+      'Arrow_Training_43746': {
+        'hash': 43746,
+        'name': 'Arrow_Training',
+        'savables': {
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Tip_59502': {
+        'hash': 59502,
+        'name': 'Tip',
+        'savables': {}
+      }
+    }
+  },
+  'Arrow_Training_Dud': {
+    'hash': 8858,
+    'name': 'Arrow_Training_Dud',
+    'embedded': {
+      'Arrow_Training_Dud_43746': {
+        'hash': 43746,
+        'name': 'Arrow_Training_Dud',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Ash_Gotera_Seed_Spray': {
+    'hash': 61862,
+    'name': 'Ash_Gotera_Seed_Spray',
+    'embedded': {
+      'Ash_Gotera_Seed_Spray_44772': {
+        'hash': 44772,
+        'name': 'Ash_Gotera_Seed_Spray',
+        'savables': {}
+      }
+    }
+  },
+  'Ash_Gotera_Smoke': {
+    'hash': 48860,
+    'name': 'Ash_Gotera_Smoke',
+    'embedded': {
+      'Ash_Gotera_Smoke_50236': {
+        'hash': 50236,
+        'name': 'Ash_Gotera_Smoke',
+        'savables': {}
+      }
+    }
+  },
+  'Ash_Pile': {
+    'hash': 53398,
+    'name': 'Ash_Pile',
+    'embedded': {
+      'Ash_Pile_41772': {
+        'hash': 41772,
+        'name': 'Ash_Pile',
+        'savables': {
+          'BasicDecay': {
+            'hash': 3801256786,
+            'name': 'BasicDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Ash_Tree_Growth': {
+    'hash': 48208,
+    'name': 'Ash_Tree_Growth',
+    'embedded': {
+      'Ash_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Ash_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Ash_Tree_Seed': {
+    'hash': 35274,
+    'name': 'Ash_Tree_Seed',
+    'embedded': {
+      'Ash_Tree_Seed_35258': {
+        'hash': 35258,
+        'name': 'Ash_Tree_Seed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Ash_Tree_Stage_1': {
+    'hash': 17892,
+    'name': 'Ash_Tree_Stage_1',
+    'embedded': {
+      'Ash_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Ash_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Assembly_Deck': {
+    'hash': 17520,
+    'name': 'Assembly_Deck',
+    'embedded': {
+      'Assembly_Deck_17438': {
+        'hash': 17438,
+        'name': 'Assembly_Deck',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'GenericAssemblyStation': {
+            'hash': 2971871217,
+            'name': 'GenericAssemblyStation'
+          }
+        }
+      },
+      'Dock_5748': {
+        'hash': 5748,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Pickup_59306': {
+        'hash': 59306,
+        'name': 'Pickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Auto_Cam_Player': {
+    'hash': 61644,
+    'name': 'Auto_Cam_Player',
+    'embedded': {}
+  },
+  'Axe_Head': {
+    'hash': 34412,
+    'name': 'Axe_Head',
+    'embedded': {
+      'Axe_Head_56484': {
+        'hash': 56484,
+        'name': 'Axe_Head',
+        'savables': {
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_59758': {
+        'hash': 59758,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Pole_7796': {
+        'hash': 7796,
+        'name': 'Insert_Pole',
+        'savables': {}
+      },
+      'metal_axeHead_curve_geo_17472': {
+        'hash': 17472,
+        'name': 'metal_axeHead_curve_geo',
+        'savables': {}
+      }
+    }
+  },
+  'Axe_Head_Curve': {
+    'hash': 50322,
+    'name': 'Axe_Head_Curve',
+    'embedded': {
+      'Axe_Head_Curve_56484': {
+        'hash': 56484,
+        'name': 'Axe_Head_Curve',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_60150': {
+        'hash': 60150,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_AxeType_7796': {
+        'hash': 7796,
+        'name': 'Insert_AxeType',
+        'savables': {}
+      },
+      'metal_axeHead_Curve_geo_LOD0_46530': {
+        'hash': 46530,
+        'name': 'metal_axeHead_Curve_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Axe_Head_Felling': {
+    'hash': 9918,
+    'name': 'Axe_Head_Felling',
+    'embedded': {
+      'Axe_Head_Felling_58934': {
+        'hash': 58934,
+        'name': 'Axe_Head_Felling',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_60560': {
+        'hash': 60560,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_AxeType_7796': {
+        'hash': 7796,
+        'name': 'Insert_AxeType',
+        'savables': {}
+      },
+      'metal_axeHead_felling_geo_LOD0_40512': {
+        'hash': 40512,
+        'name': 'metal_axeHead_felling_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Axe_Head_GreatCurve': {
+    'hash': 10056,
+    'name': 'Axe_Head_GreatCurve',
+    'embedded': {
+      'Axe_Head_GreatCurve_39022': {
+        'hash': 39022,
+        'name': 'Axe_Head_GreatCurve',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_61024': {
+        'hash': 61024,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_7796': {
+        'hash': 7796,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      },
+      'metal_axeHead_greatCurve_geo_LOD0_47596': {
+        'hash': 47596,
+        'name': 'metal_axeHead_greatCurve_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Axe_Head_LShape': {
+    'hash': 17400,
+    'name': 'Axe_Head_LShape',
+    'embedded': {
+      'Axe_Head_LShape_25390': {
+        'hash': 25390,
+        'name': 'Axe_Head_LShape',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_61514': {
+        'hash': 61514,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_AxeType_7796': {
+        'hash': 7796,
+        'name': 'Insert_AxeType',
+        'savables': {}
+      },
+      'metal_axeHead_Lshape_LOD0_22814': {
+        'hash': 22814,
+        'name': 'metal_axeHead_Lshape_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Axe_Training': {
+    'hash': 57010,
+    'name': 'Axe_Training',
+    'embedded': {}
+  },
+  'Babu': {
+    'hash': 9140,
+    'name': 'Babu',
+    'embedded': {
+      'Babu_55348': {
+        'hash': 55348,
+        'name': 'Babu',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Babu_AI_55590': {
+        'hash': 55590,
+        'name': 'Babu_AI',
+        'savables': {}
+      },
+      'Body_41706': {
+        'hash': 41706,
+        'name': 'Body',
+        'savables': {}
+      },
+      'Dig_Spawn_65330': {
+        'hash': 65330,
+        'name': 'Dig_Spawn',
+        'savables': {}
+      },
+      'Drop_Spawn_3448': {
+        'hash': 3448,
+        'name': 'Drop_Spawn',
+        'savables': {}
+      },
+      'Head_Collision_43064': {
+        'hash': 43064,
+        'name': 'Head_Collision',
+        'savables': {}
+      },
+      'Interactor_49402': {
+        'hash': 49402,
+        'name': 'Interactor',
+        'savables': {}
+      },
+      'babu_tusk_L_(1)_16632': {
+        'hash': 16632,
+        'name': 'babu_tusk_L_(1)',
+        'savables': {}
+      },
+      'babu_tusk_R_(1)_17014': {
+        'hash': 17014,
+        'name': 'babu_tusk_R_(1)',
+        'savables': {}
+      }
+    }
+  },
+  'Babu_Leg_Bone': {
+    'hash': 32526,
+    'name': 'Babu_Leg_Bone',
+    'embedded': {
+      'Babu_Leg_Bone_26390': {
+        'hash': 26390,
+        'name': 'Babu_Leg_Bone',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Babu_Leg_Full_Burnt': {
+    'hash': 64844,
+    'name': 'Babu_Leg_Full_Burnt',
+    'embedded': {
+      'Babu_Leg_Full_Burnt_25250': {
+        'hash': 25250,
+        'name': 'Babu_Leg_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Bone_Spawner_38786': {
+        'hash': 38786,
+        'name': 'Bone_Spawner',
+        'savables': {}
+      },
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Babu_Leg_Full_Cooked': {
+    'hash': 42916,
+    'name': 'Babu_Leg_Full_Cooked',
+    'embedded': {
+      'Babu_Leg_Full_Cooked_25250': {
+        'hash': 25250,
+        'name': 'Babu_Leg_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Bone_Spawner_38786': {
+        'hash': 38786,
+        'name': 'Bone_Spawner',
+        'savables': {}
+      },
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Babu_Leg_Full_Ripe': {
+    'hash': 2562,
+    'name': 'Babu_Leg_Full_Ripe',
+    'embedded': {
+      'Babu_Leg_Full_Ripe_25250': {
+        'hash': 25250,
+        'name': 'Babu_Leg_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Bone_Spawner_38786': {
+        'hash': 38786,
+        'name': 'Bone_Spawner',
+        'savables': {}
+      },
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Babu_Leg_Half_Burnt': {
+    'hash': 50328,
+    'name': 'Babu_Leg_Half_Burnt',
+    'embedded': {
+      'Babu_Leg_Half_Burnt_16238': {
+        'hash': 16238,
+        'name': 'Babu_Leg_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_16182': {
+        'hash': 16182,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Babu_Leg_Half_Cooked': {
+    'hash': 50326,
+    'name': 'Babu_Leg_Half_Cooked',
+    'embedded': {
+      'Babu_Leg_Half_Cooked_16238': {
+        'hash': 16238,
+        'name': 'Babu_Leg_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_16182': {
+        'hash': 16182,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Babu_Leg_Half_Ripe': {
+    'hash': 50252,
+    'name': 'Babu_Leg_Half_Ripe',
+    'embedded': {
+      'Babu_Leg_Half_Ripe_16238': {
+        'hash': 16238,
+        'name': 'Babu_Leg_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_16182': {
+        'hash': 16182,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Bag': {
+    'hash': 35324,
+    'name': 'Bag',
+    'embedded': {
+      'Bag_43012': {
+        'hash': 43012,
+        'name': 'Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Dock_BL_42978': {
+        'hash': 42978,
+        'name': 'Dock_BL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BM_42976': {
+        'hash': 42976,
+        'name': 'Dock_BM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BR_42974': {
+        'hash': 42974,
+        'name': 'Dock_BR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_ML_42984': {
+        'hash': 42984,
+        'name': 'Dock_ML',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MM_42982': {
+        'hash': 42982,
+        'name': 'Dock_MM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MR_42980': {
+        'hash': 42980,
+        'name': 'Dock_MR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TL_42990': {
+        'hash': 42990,
+        'name': 'Dock_TL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TM_42988': {
+        'hash': 42988,
+        'name': 'Dock_TM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TR_42986': {
+        'hash': 42986,
+        'name': 'Dock_TR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Roll_Dock_47074': {
+        'hash': 47074,
+        'name': 'Roll_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Slot_Bag_Attach_30776': {
+        'hash': 30776,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_55164': {
+        'hash': 55164,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Pin_Collectible_Attach_31454': {
+        'hash': 31454,
+        'name': 'Slot_Bag_Pin_Collectible_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Tool_Attachment_36292': {
+        'hash': 36292,
+        'name': 'Slot_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'Slot_Bag_Tool_Attachment_36386': {
+        'hash': 36386,
+        'name': 'Slot_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'standard_bag_Body_14336': {
+        'hash': 14336,
+        'name': 'standard_bag_Body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_backPin_L_14300': {
+        'hash': 14300,
+        'name': 'standard_bag_backPin_L',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_backPin_R_14296': {
+        'hash': 14296,
+        'name': 'standard_bag_backPin_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_crossStrap_01_14332': {
+        'hash': 14332,
+        'name': 'standard_bag_crossStrap_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_flap_14328': {
+        'hash': 14328,
+        'name': 'standard_bag_flap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_flap_clasp_01_14324': {
+        'hash': 14324,
+        'name': 'standard_bag_flap_clasp_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_handle_body_14308': {
+        'hash': 14308,
+        'name': 'standard_bag_handle_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_handle_wraps_14304': {
+        'hash': 14304,
+        'name': 'standard_bag_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_sideBuckle_L_01_14316': {
+        'hash': 14316,
+        'name': 'standard_bag_sideBuckle_L_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_sideBuckle_L_02_14312': {
+        'hash': 14312,
+        'name': 'standard_bag_sideBuckle_L_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_sideBuckle_R_01_14376': {
+        'hash': 14376,
+        'name': 'standard_bag_sideBuckle_R_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_sideBuckle_R_02_14372': {
+        'hash': 14372,
+        'name': 'standard_bag_sideBuckle_R_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_bot_L_01_14360': {
+        'hash': 14360,
+        'name': 'standard_bag_strap_bot_L_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_bot_R_01_14356': {
+        'hash': 14356,
+        'name': 'standard_bag_strap_bot_R_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_bot_buckle_L_02_14368': {
+        'hash': 14368,
+        'name': 'standard_bag_strap_bot_buckle_L_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_bot_buckle_R_02_14364': {
+        'hash': 14364,
+        'name': 'standard_bag_strap_bot_buckle_R_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_top_L_01_14344': {
+        'hash': 14344,
+        'name': 'standard_bag_strap_top_L_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_top_R_01_14340': {
+        'hash': 14340,
+        'name': 'standard_bag_strap_top_R_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_top_buckle_L_01_14352': {
+        'hash': 14352,
+        'name': 'standard_bag_strap_top_buckle_L_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_strap_top_buckle_R_01_14348': {
+        'hash': 14348,
+        'name': 'standard_bag_strap_top_buckle_R_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Barrel_Bag': {
+    'hash': 19354,
+    'name': 'Barrel_Bag',
+    'embedded': {
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Barrel_Bag_43012': {
+        'hash': 43012,
+        'name': 'Barrel_Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Dock_TL_42990': {
+        'hash': 42990,
+        'name': 'Dock_TL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Heat_47560': {
+        'hash': 47560,
+        'name': 'Heat',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Liquid_Part_65316': {
+        'hash': 65316,
+        'name': 'Liquid_Part',
+        'savables': {
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          }
+        }
+      },
+      'Slot_Bag_Attach_30776': {
+        'hash': 30776,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_55164': {
+        'hash': 55164,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'barrel_bag_bottomCap_37710': {
+        'hash': 37710,
+        'name': 'barrel_bag_bottomCap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_handleRod_37706': {
+        'hash': 37706,
+        'name': 'barrel_bag_handleRod',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_handleTop_37702': {
+        'hash': 37702,
+        'name': 'barrel_bag_handleTop',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_ladleHook_37698': {
+        'hash': 37698,
+        'name': 'barrel_bag_ladleHook',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_01_37746': {
+        'hash': 37746,
+        'name': 'barrel_bag_plank_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_02_37742': {
+        'hash': 37742,
+        'name': 'barrel_bag_plank_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_03_37738': {
+        'hash': 37738,
+        'name': 'barrel_bag_plank_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_04_37734': {
+        'hash': 37734,
+        'name': 'barrel_bag_plank_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_05_37730': {
+        'hash': 37730,
+        'name': 'barrel_bag_plank_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_06_37726': {
+        'hash': 37726,
+        'name': 'barrel_bag_plank_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_07_37714': {
+        'hash': 37714,
+        'name': 'barrel_bag_plank_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_plank_08_37722': {
+        'hash': 37722,
+        'name': 'barrel_bag_plank_08',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_ringBottom_37718': {
+        'hash': 37718,
+        'name': 'barrel_bag_ringBottom',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'barrel_bag_ringtop_37750': {
+        'hash': 37750,
+        'name': 'barrel_bag_ringtop',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Basic_Population_Folder': {
+    'hash': 31116,
+    'name': 'Basic_Population_Folder',
+    'embedded': {}
+  },
+  'Birch_Tree_Growth': {
+    'hash': 48218,
+    'name': 'Birch_Tree_Growth',
+    'embedded': {
+      'Birch_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Birch_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Birch_Tree_Seed': {
+    'hash': 55274,
+    'name': 'Birch_Tree_Seed',
+    'embedded': {
+      'Birch_Tree_Seed_35258': {
+        'hash': 35258,
+        'name': 'Birch_Tree_Seed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Birch_Tree_Stage_1': {
+    'hash': 17704,
+    'name': 'Birch_Tree_Stage_1',
+    'embedded': {
+      'Birch_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Birch_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Blue_Mix_Recipe_Burnt_Stew': {
+    'hash': 57666,
+    'name': 'Blue_Mix_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Blue_Mix_Recipe_Cooked_Stew': {
+    'hash': 57642,
+    'name': 'Blue_Mix_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Blue_Mix_Recipe_Raw_Stew': {
+    'hash': 57614,
+    'name': 'Blue_Mix_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Blueberry_Flower_Bloom': {
+    'hash': 40922,
+    'name': 'Blueberry_Flower_Bloom',
+    'embedded': {
+      'Blueberry_Flower_Bloom_25566': {
+        'hash': 25566,
+        'name': 'Blueberry_Flower_Bloom',
+        'savables': {}
+      }
+    }
+  },
+  'Blueberry_Flower_Bud': {
+    'hash': 40920,
+    'name': 'Blueberry_Flower_Bud',
+    'embedded': {
+      'Blueberry_Flower_Bud_25268': {
+        'hash': 25268,
+        'name': 'Blueberry_Flower_Bud',
+        'savables': {}
+      }
+    }
+  },
+  'Blueberry_Full_Burnt': {
+    'hash': 49890,
+    'name': 'Blueberry_Full_Burnt',
+    'embedded': {
+      'Blueberry_Full_Burnt_56526': {
+        'hash': 56526,
+        'name': 'Blueberry_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_46248': {
+        'hash': 46248,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Full_Cooked': {
+    'hash': 47468,
+    'name': 'Blueberry_Full_Cooked',
+    'embedded': {
+      'Blueberry_Full_Cooked_55520': {
+        'hash': 55520,
+        'name': 'Blueberry_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_45334': {
+        'hash': 45334,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Full_Ripe': {
+    'hash': 45012,
+    'name': 'Blueberry_Full_Ripe',
+    'embedded': {
+      'Blueberry_Full_Ripe_54516': {
+        'hash': 54516,
+        'name': 'Blueberry_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_44398': {
+        'hash': 44398,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Full_Unripe': {
+    'hash': 42556,
+    'name': 'Blueberry_Full_Unripe',
+    'embedded': {
+      'Blueberry_Full_Unripe_53512': {
+        'hash': 53512,
+        'name': 'Blueberry_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      },
+      'Cooking_43444': {
+        'hash': 43444,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Growth': {
+    'hash': 19292,
+    'name': 'Blueberry_Growth',
+    'embedded': {
+      'Blueberry_Growth_33458': {
+        'hash': 33458,
+        'name': 'Blueberry_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Recipe_Burnt_Stew': {
+    'hash': 36830,
+    'name': 'Blueberry_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Blueberry_Recipe_Cooked_Stew': {
+    'hash': 36086,
+    'name': 'Blueberry_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Blueberry_Recipe_Raw_Stew': {
+    'hash': 35338,
+    'name': 'Blueberry_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Blueberry_Tree': {
+    'hash': 878,
+    'name': 'Blueberry_Tree',
+    'embedded': {
+      'Blueberry_Tree_24412': {
+        'hash': 24412,
+        'name': 'Blueberry_Tree',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Tree_Growth': {
+    'hash': 14700,
+    'name': 'Blueberry_Tree_Growth',
+    'embedded': {
+      'Blueberry_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Blueberry_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Blueberry_Tree_Separated': {
+    'hash': 13784,
+    'name': 'Blueberry_Tree_Separated',
+    'embedded': {}
+  },
+  'Blueberry_Tree_Stage_1': {
+    'hash': 26588,
+    'name': 'Blueberry_Tree_Stage_1',
+    'embedded': {
+      'Blueberry_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Blueberry_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Blueberry_Tree_Stage_2': {
+    'hash': 1038,
+    'name': 'Blueberry_Tree_Stage_2',
+    'embedded': {
+      'Blueberry_Tree_Stage_2_1020': {
+        'hash': 1020,
+        'name': 'Blueberry_Tree_Stage_2',
+        'savables': {}
+      }
+    }
+  },
+  'Blueberry_Tree_Stage_3': {
+    'hash': 1040,
+    'name': 'Blueberry_Tree_Stage_3',
+    'embedded': {
+      'Blueberry_Tree_Stage_3_1022': {
+        'hash': 1022,
+        'name': 'Blueberry_Tree_Stage_3',
+        'savables': {}
+      }
+    }
+  },
+  'Book': {
+    'hash': 44174,
+    'name': 'Book',
+    'embedded': {}
+  },
+  'Bookshelf': {
+    'hash': 64316,
+    'name': 'Bookshelf',
+    'embedded': {
+      'Bookshelf_64030': {
+        'hash': 64030,
+        'name': 'Bookshelf',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64568': {
+        'hash': 64568,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64570': {
+        'hash': 64570,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64572': {
+        'hash': 64572,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64574': {
+        'hash': 64574,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64576': {
+        'hash': 64576,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64578': {
+        'hash': 64578,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64580': {
+        'hash': 64580,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64582': {
+        'hash': 64582,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64584': {
+        'hash': 64584,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64586': {
+        'hash': 64586,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64588': {
+        'hash': 64588,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64590': {
+        'hash': 64590,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64592': {
+        'hash': 64592,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64594': {
+        'hash': 64594,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64596': {
+        'hash': 64596,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64598': {
+        'hash': 64598,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64600': {
+        'hash': 64600,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64602': {
+        'hash': 64602,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_64604': {
+        'hash': 64604,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Bookshelf_NoBackboard': {
+    'hash': 59952,
+    'name': 'Bookshelf_NoBackboard',
+    'embedded': {
+      'Bookshelf_NoBackboard_64030': {
+        'hash': 64030,
+        'name': 'Bookshelf_NoBackboard',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62044': {
+        'hash': 62044,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62046': {
+        'hash': 62046,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62048': {
+        'hash': 62048,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62050': {
+        'hash': 62050,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62052': {
+        'hash': 62052,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62054': {
+        'hash': 62054,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62056': {
+        'hash': 62056,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62058': {
+        'hash': 62058,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62060': {
+        'hash': 62060,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62062': {
+        'hash': 62062,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62064': {
+        'hash': 62064,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62066': {
+        'hash': 62066,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62068': {
+        'hash': 62068,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62070': {
+        'hash': 62070,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62072': {
+        'hash': 62072,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62074': {
+        'hash': 62074,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62076': {
+        'hash': 62076,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62080': {
+        'hash': 62080,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Bought_Skill_Orb_Replacer': {
+    'hash': 42842,
+    'name': 'Bought_Skill_Orb_Replacer',
+    'embedded': {}
+  },
+  'Boulder_Button_Spawner': {
+    'hash': 21830,
+    'name': 'Boulder_Button_Spawner',
+    'embedded': {}
+  },
+  'Bouncing_Movement': {
+    'hash': 34396,
+    'name': 'Bouncing_Movement',
+    'embedded': {
+      'Bouncing_Movement_60930': {
+        'hash': 60930,
+        'name': 'Bouncing_Movement',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      }
+    }
+  },
+  'Bow': {
+    'hash': 56546,
+    'name': 'Bow',
+    'embedded': {
+      'Arrow_Dock_40686': {
+        'hash': 40686,
+        'name': 'Arrow_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bow_40716': {
+        'hash': 40716,
+        'name': 'Bow',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'String_40688': {
+        'hash': 40688,
+        'name': 'String',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Bow_Blade': {
+    'hash': 27416,
+    'name': 'Bow_Blade',
+    'embedded': {
+      'Bow_Blade_27418': {
+        'hash': 27418,
+        'name': 'Bow_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_12228': {
+        'hash': 12228,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Bow_Blade_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bow_Blade',
+        'savables': {}
+      },
+      'metal_blade_bow_full_geo_LOD0_52240': {
+        'hash': 52240,
+        'name': 'metal_blade_bow_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Bow_Training': {
+    'hash': 42340,
+    'name': 'Bow_Training',
+    'embedded': {
+      'Arrow_Dock_40686': {
+        'hash': 40686,
+        'name': 'Arrow_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bow_Training_42328': {
+        'hash': 42328,
+        'name': 'Bow_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'String_40688': {
+        'hash': 40688,
+        'name': 'String',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Bramble_Obstacle': {
+    'hash': 59178,
+    'name': 'Bramble_Obstacle',
+    'embedded': {
+      'Bramble_Obstacle_59546': {
+        'hash': 59546,
+        'name': 'Bramble_Obstacle',
+        'savables': {}
+      }
+    }
+  },
+  'Bramble_Obstacle_No_Bush': {
+    'hash': 24434,
+    'name': 'Bramble_Obstacle_No_Bush',
+    'embedded': {
+      'Bramble_Obstacle_No_Bush_24428': {
+        'hash': 24428,
+        'name': 'Bramble_Obstacle_No_Bush',
+        'savables': {}
+      }
+    }
+  },
+  'Breakable_Box': {
+    'hash': 19624,
+    'name': 'Breakable_Box',
+    'embedded': {
+      'Breakable_Box_17050': {
+        'hash': 17050,
+        'name': 'Breakable_Box',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Content_40226': {
+        'hash': 40226,
+        'name': 'Spawn_Content',
+        'savables': {}
+      }
+    }
+  },
+  'Breakable_Pot': {
+    'hash': 60800,
+    'name': 'Breakable_Pot',
+    'embedded': {
+      'Breakable_Pot_17050': {
+        'hash': 17050,
+        'name': 'Breakable_Pot',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Content_40226': {
+        'hash': 40226,
+        'name': 'Spawn_Content',
+        'savables': {}
+      }
+    }
+  },
+  'Breakable_Root_2.5m_Bendy': {
+    'hash': 35896,
+    'name': 'Breakable_Root_2.5m_Bendy',
+    'embedded': {
+      'Breakable_Root_2.5m_Bendy_35892': {
+        'hash': 35892,
+        'name': 'Breakable_Root_2.5m_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_2.5m_Curved': {
+    'hash': 35738,
+    'name': 'Breakable_Root_2.5m_Curved',
+    'embedded': {
+      'Breakable_Root_2.5m_Curved_35734': {
+        'hash': 35734,
+        'name': 'Breakable_Root_2.5m_Curved',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_2.5m_Straight': {
+    'hash': 34564,
+    'name': 'Breakable_Root_2.5m_Straight',
+    'embedded': {
+      'Breakable_Root_2.5m_Straight_34560': {
+        'hash': 34560,
+        'name': 'Breakable_Root_2.5m_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_2.5m_Wavy': {
+    'hash': 36054,
+    'name': 'Breakable_Root_2.5m_Wavy',
+    'embedded': {
+      'Breakable_Root_2.5m_Wavy_36050': {
+        'hash': 36050,
+        'name': 'Breakable_Root_2.5m_Wavy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Bendy': {
+    'hash': 41482,
+    'name': 'Breakable_Root_Bendy',
+    'embedded': {
+      'Breakable_Root_Bendy_42186': {
+        'hash': 42186,
+        'name': 'Breakable_Root_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Curved': {
+    'hash': 64388,
+    'name': 'Breakable_Root_Curved',
+    'embedded': {
+      'Breakable_Root_Curved_2746': {
+        'hash': 2746,
+        'name': 'Breakable_Root_Curved',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Fence': {
+    'hash': 62846,
+    'name': 'Breakable_Root_Fence',
+    'embedded': {
+      'Breakable_Root_Fence_63540': {
+        'hash': 63540,
+        'name': 'Breakable_Root_Fence',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Ground_01': {
+    'hash': 34014,
+    'name': 'Breakable_Root_Ground_01',
+    'embedded': {
+      'Breakable_Root_Ground_01_34010': {
+        'hash': 34010,
+        'name': 'Breakable_Root_Ground_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Ground_02': {
+    'hash': 23246,
+    'name': 'Breakable_Root_Ground_02',
+    'embedded': {
+      'Breakable_Root_Ground_02_23250': {
+        'hash': 23250,
+        'name': 'Breakable_Root_Ground_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Ground_03': {
+    'hash': 21206,
+    'name': 'Breakable_Root_Ground_03',
+    'embedded': {
+      'Breakable_Root_Ground_03_21202': {
+        'hash': 21202,
+        'name': 'Breakable_Root_Ground_03',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Ground_04': {
+    'hash': 18702,
+    'name': 'Breakable_Root_Ground_04',
+    'embedded': {
+      'Breakable_Root_Ground_04_18706': {
+        'hash': 18706,
+        'name': 'Breakable_Root_Ground_04',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Ground_05': {
+    'hash': 16298,
+    'name': 'Breakable_Root_Ground_05',
+    'embedded': {
+      'Breakable_Root_Ground_05_16294': {
+        'hash': 16294,
+        'name': 'Breakable_Root_Ground_05',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Ground_06': {
+    'hash': 13634,
+    'name': 'Breakable_Root_Ground_06',
+    'embedded': {
+      'Breakable_Root_Ground_06_13638': {
+        'hash': 13638,
+        'name': 'Breakable_Root_Ground_06',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_HangingShort_Bendy': {
+    'hash': 13856,
+    'name': 'Breakable_Root_HangingShort_Bendy',
+    'embedded': {
+      'Breakable_Root_HangingShort_Bendy_13860': {
+        'hash': 13860,
+        'name': 'Breakable_Root_HangingShort_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_HangingShort_Curved': {
+    'hash': 12224,
+    'name': 'Breakable_Root_HangingShort_Curved',
+    'embedded': {
+      'Breakable_Root_HangingShort_Curved_12228': {
+        'hash': 12228,
+        'name': 'Breakable_Root_HangingShort_Curved',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_HangingShort_Straight': {
+    'hash': 9226,
+    'name': 'Breakable_Root_HangingShort_Straight',
+    'embedded': {
+      'Breakable_Root_HangingShort_Straight_9230': {
+        'hash': 9230,
+        'name': 'Breakable_Root_HangingShort_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_HangingShort_Wavy': {
+    'hash': 8534,
+    'name': 'Breakable_Root_HangingShort_Wavy',
+    'embedded': {
+      'Breakable_Root_HangingShort_Wavy_8538': {
+        'hash': 8538,
+        'name': 'Breakable_Root_HangingShort_Wavy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Hanging_Bendy': {
+    'hash': 63792,
+    'name': 'Breakable_Root_Hanging_Bendy',
+    'embedded': {
+      'Breakable_Root_Hanging_Bendy_63796': {
+        'hash': 63796,
+        'name': 'Breakable_Root_Hanging_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Hanging_Column_01': {
+    'hash': 37666,
+    'name': 'Breakable_Root_Hanging_Column_01',
+    'embedded': {
+      'Breakable_Root_Hanging_Column_01_37662': {
+        'hash': 37662,
+        'name': 'Breakable_Root_Hanging_Column_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Hanging_Column_02': {
+    'hash': 24548,
+    'name': 'Breakable_Root_Hanging_Column_02',
+    'embedded': {
+      'Breakable_Root_Hanging_Column_02_24552': {
+        'hash': 24552,
+        'name': 'Breakable_Root_Hanging_Column_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Hanging_Straight': {
+    'hash': 12714,
+    'name': 'Breakable_Root_Hanging_Straight',
+    'embedded': {
+      'Breakable_Root_Hanging_Straight_12710': {
+        'hash': 12710,
+        'name': 'Breakable_Root_Hanging_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Hanging_Thin_Bendy': {
+    'hash': 6394,
+    'name': 'Breakable_Root_Hanging_Thin_Bendy',
+    'embedded': {
+      'Breakable_Root_Hanging_Thin_Bendy_6398': {
+        'hash': 6398,
+        'name': 'Breakable_Root_Hanging_Thin_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Hanging_Thin_Straight': {
+    'hash': 57168,
+    'name': 'Breakable_Root_Hanging_Thin_Straight',
+    'embedded': {
+      'Breakable_Root_Hanging_Thin_Straight_57164': {
+        'hash': 57164,
+        'name': 'Breakable_Root_Hanging_Thin_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Mound_Large': {
+    'hash': 15602,
+    'name': 'Breakable_Root_Mound_Large',
+    'embedded': {
+      'Breakable_Root_Mound_Large_15598': {
+        'hash': 15598,
+        'name': 'Breakable_Root_Mound_Large',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Mound_Small': {
+    'hash': 43010,
+    'name': 'Breakable_Root_Mound_Small',
+    'embedded': {
+      'Breakable_Root_Mound_Small_43014': {
+        'hash': 43014,
+        'name': 'Breakable_Root_Mound_Small',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Spawner': {
+    'hash': 40946,
+    'name': 'Breakable_Root_Spawner',
+    'embedded': {
+      'Breakable_Root_Spawner_6790': {
+        'hash': 6790,
+        'name': 'Breakable_Root_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Straight': {
+    'hash': 47012,
+    'name': 'Breakable_Root_Straight',
+    'embedded': {
+      'Breakable_Root_Straight_47710': {
+        'hash': 47710,
+        'name': 'Breakable_Root_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Breakable_Root_Wavy': {
+    'hash': 28332,
+    'name': 'Breakable_Root_Wavy',
+    'embedded': {
+      'Breakable_Root_Wavy_28960': {
+        'hash': 28960,
+        'name': 'Breakable_Root_Wavy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Box_Piece': {
+    'hash': 260,
+    'name': 'Broken_Box_Piece',
+    'embedded': {
+      'Broken_Box_Piece_1356': {
+        'hash': 1356,
+        'name': 'Broken_Box_Piece',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Breakable_Root_Piece_Ground': {
+    'hash': 43996,
+    'name': 'Broken_Breakable_Root_Piece_Ground',
+    'embedded': {
+      'Broken_Breakable_Root_Piece_Ground_45852': {
+        'hash': 45852,
+        'name': 'Broken_Breakable_Root_Piece_Ground',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Breakable_Root_Piece_Short': {
+    'hash': 43998,
+    'name': 'Broken_Breakable_Root_Piece_Short',
+    'embedded': {
+      'Broken_Breakable_Root_Piece_Short_45854': {
+        'hash': 45854,
+        'name': 'Broken_Breakable_Root_Piece_Short',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Breakable_Root_Piece_Thick': {
+    'hash': 43994,
+    'name': 'Broken_Breakable_Root_Piece_Thick',
+    'embedded': {
+      'Broken_Breakable_Root_Piece_Thick_45850': {
+        'hash': 45850,
+        'name': 'Broken_Breakable_Root_Piece_Thick',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Breakable_Root_Piece_Thin': {
+    'hash': 44000,
+    'name': 'Broken_Breakable_Root_Piece_Thin',
+    'embedded': {
+      'Broken_Breakable_Root_Piece_Thin_45856': {
+        'hash': 45856,
+        'name': 'Broken_Breakable_Root_Piece_Thin',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Burnable_Root_Piece_Ground': {
+    'hash': 60406,
+    'name': 'Broken_Burnable_Root_Piece_Ground',
+    'embedded': {
+      'Broken_Burnable_Root_Piece_Ground_21172': {
+        'hash': 21172,
+        'name': 'Broken_Burnable_Root_Piece_Ground',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Burnable_Root_Piece_Short': {
+    'hash': 58460,
+    'name': 'Broken_Burnable_Root_Piece_Short',
+    'embedded': {
+      'Broken_Burnable_Root_Piece_Short_21416': {
+        'hash': 21416,
+        'name': 'Broken_Burnable_Root_Piece_Short',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Burnable_Root_Piece_Thick': {
+    'hash': 64302,
+    'name': 'Broken_Burnable_Root_Piece_Thick',
+    'embedded': {
+      'Broken_Burnable_Root_Piece_Thick_20728': {
+        'hash': 20728,
+        'name': 'Broken_Burnable_Root_Piece_Thick',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Burnable_Root_Piece_Thin': {
+    'hash': 61492,
+    'name': 'Broken_Burnable_Root_Piece_Thin',
+    'embedded': {
+      'Broken_Burnable_Root_Piece_Thin_21074': {
+        'hash': 21074,
+        'name': 'Broken_Burnable_Root_Piece_Thin',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Crystal_Piece_01': {
+    'hash': 60484,
+    'name': 'Broken_Crystal_Piece_01',
+    'embedded': {
+      'Broken_Crystal_Piece_01_63000': {
+        'hash': 63000,
+        'name': 'Broken_Crystal_Piece_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Crystal_Piece_02': {
+    'hash': 49198,
+    'name': 'Broken_Crystal_Piece_02',
+    'embedded': {
+      'Broken_Crystal_Piece_02_46364': {
+        'hash': 46364,
+        'name': 'Broken_Crystal_Piece_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Crystal_Piece_03': {
+    'hash': 37046,
+    'name': 'Broken_Crystal_Piece_03',
+    'embedded': {
+      'Broken_Crystal_Piece_03_34076': {
+        'hash': 34076,
+        'name': 'Broken_Crystal_Piece_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Crystal_Piece_04': {
+    'hash': 23220,
+    'name': 'Broken_Crystal_Piece_04',
+    'embedded': {
+      'Broken_Crystal_Piece_04_20126': {
+        'hash': 20126,
+        'name': 'Broken_Crystal_Piece_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_ExplosionBoulder_Part_01': {
+    'hash': 45514,
+    'name': 'Broken_ExplosionBoulder_Part_01',
+    'embedded': {
+      'Broken_ExplosionBoulder_Part_01_53690': {
+        'hash': 53690,
+        'name': 'Broken_ExplosionBoulder_Part_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_ExplosionBoulder_Part_02': {
+    'hash': 45518,
+    'name': 'Broken_ExplosionBoulder_Part_02',
+    'embedded': {
+      'Broken_ExplosionBoulder_Part_02_3998': {
+        'hash': 3998,
+        'name': 'Broken_ExplosionBoulder_Part_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_ExplosionBoulder_Part_03': {
+    'hash': 45516,
+    'name': 'Broken_ExplosionBoulder_Part_03',
+    'embedded': {
+      'Broken_ExplosionBoulder_Part_03_39886': {
+        'hash': 39886,
+        'name': 'Broken_ExplosionBoulder_Part_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_ExplosionBoulder_Part_04': {
+    'hash': 45512,
+    'name': 'Broken_ExplosionBoulder_Part_04',
+    'embedded': {
+      'Broken_ExplosionBoulder_Part_04_29214': {
+        'hash': 29214,
+        'name': 'Broken_ExplosionBoulder_Part_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_ExplosionBoulder_Part_05': {
+    'hash': 45520,
+    'name': 'Broken_ExplosionBoulder_Part_05',
+    'embedded': {
+      'Broken_ExplosionBoulder_Part_05_18196': {
+        'hash': 18196,
+        'name': 'Broken_ExplosionBoulder_Part_05',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Broken_Vine_Bunch_Dead_Piece': {
+    'hash': 7264,
+    'name': 'Broken_Vine_Bunch_Dead_Piece',
+    'embedded': {
+      'Broken_Vine_Bunch_Dead_Piece_11182': {
+        'hash': 11182,
+        'name': 'Broken_Vine_Bunch_Dead_Piece',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Bronze_Alloy_Ingot': {
+    'hash': 26316,
+    'name': 'Bronze_Alloy_Ingot',
+    'embedded': {}
+  },
+  'Brown_Mushroom_Shield': {
+    'hash': 17258,
+    'name': 'Brown_Mushroom_Shield',
+    'embedded': {
+      'Brown_Mushroom_Shield_15482': {
+        'hash': 15482,
+        'name': 'Brown_Mushroom_Shield',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Bung': {
+    'hash': 8050,
+    'name': 'Bung',
+    'embedded': {}
+  },
+  'Buried_Grass': {
+    'hash': 47090,
+    'name': 'Buried_Grass',
+    'embedded': {
+      'Buried_Grass_64192': {
+        'hash': 64192,
+        'name': 'Buried_Grass',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Buried_Pullup': {
+    'hash': 61742,
+    'name': 'Buried_Pullup',
+    'embedded': {
+      'Buried_Pullup_64192': {
+        'hash': 64192,
+        'name': 'Buried_Pullup',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Buried_Pullup_Bramble': {
+    'hash': 37764,
+    'name': 'Buried_Pullup_Bramble',
+    'embedded': {
+      'Buried_Pullup_Bramble_64192': {
+        'hash': 64192,
+        'name': 'Buried_Pullup_Bramble',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Buried_Pullup_Carrot': {
+    'hash': 59026,
+    'name': 'Buried_Pullup_Carrot',
+    'embedded': {
+      'Buried_Pullup_Carrot_59022': {
+        'hash': 59022,
+        'name': 'Buried_Pullup_Carrot',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Buried_Pullup_Potato_Sapling': {
+    'hash': 10960,
+    'name': 'Buried_Pullup_Potato_Sapling',
+    'embedded': {
+      'Buried_Pullup_Potato_Sapling_64192': {
+        'hash': 64192,
+        'name': 'Buried_Pullup_Potato_Sapling',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Buried_Pullup_Primitive': {
+    'hash': 29550,
+    'name': 'Buried_Pullup_Primitive',
+    'embedded': {
+      'Buried_Pullup_Primitive_64192': {
+        'hash': 64192,
+        'name': 'Buried_Pullup_Primitive',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Fence': {
+    'hash': 45144,
+    'name': 'Burnable_Root_Fence',
+    'embedded': {
+      'Burnable_Root_Fence_63540': {
+        'hash': 63540,
+        'name': 'Burnable_Root_Fence',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Ground_01': {
+    'hash': 5702,
+    'name': 'Burnable_Root_Ground_01',
+    'embedded': {
+      'Burnable_Root_Ground_01_10714': {
+        'hash': 10714,
+        'name': 'Burnable_Root_Ground_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Ground_02': {
+    'hash': 34852,
+    'name': 'Burnable_Root_Ground_02',
+    'embedded': {
+      'Burnable_Root_Ground_02_36732': {
+        'hash': 36732,
+        'name': 'Burnable_Root_Ground_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Ground_03': {
+    'hash': 65260,
+    'name': 'Burnable_Root_Ground_03',
+    'embedded': {
+      'Burnable_Root_Ground_03_2088': {
+        'hash': 2088,
+        'name': 'Burnable_Root_Ground_03',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Ground_04': {
+    'hash': 36342,
+    'name': 'Burnable_Root_Ground_04',
+    'embedded': {
+      'Burnable_Root_Ground_04_38842': {
+        'hash': 38842,
+        'name': 'Burnable_Root_Ground_04',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Ground_05': {
+    'hash': 35154,
+    'name': 'Burnable_Root_Ground_05',
+    'embedded': {
+      'Burnable_Root_Ground_05_37204': {
+        'hash': 37204,
+        'name': 'Burnable_Root_Ground_05',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Ground_06': {
+    'hash': 37414,
+    'name': 'Burnable_Root_Ground_06',
+    'embedded': {
+      'Burnable_Root_Ground_06_59980': {
+        'hash': 59980,
+        'name': 'Burnable_Root_Ground_06',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_HangingShort_Bendy': {
+    'hash': 58042,
+    'name': 'Burnable_Root_HangingShort_Bendy',
+    'embedded': {
+      'Burnable_Root_HangingShort_Bendy_60188': {
+        'hash': 60188,
+        'name': 'Burnable_Root_HangingShort_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_HangingShort_Curved': {
+    'hash': 29008,
+    'name': 'Burnable_Root_HangingShort_Curved',
+    'embedded': {
+      'Burnable_Root_HangingShort_Curved_31246': {
+        'hash': 31246,
+        'name': 'Burnable_Root_HangingShort_Curved',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_HangingShort_Straight': {
+    'hash': 43200,
+    'name': 'Burnable_Root_HangingShort_Straight',
+    'embedded': {
+      'Burnable_Root_HangingShort_Straight_45316': {
+        'hash': 45316,
+        'name': 'Burnable_Root_HangingShort_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_HangingShort_Wavy': {
+    'hash': 680,
+    'name': 'Burnable_Root_HangingShort_Wavy',
+    'embedded': {
+      'Burnable_Root_HangingShort_Wavy_3040': {
+        'hash': 3040,
+        'name': 'Burnable_Root_HangingShort_Wavy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Hanging_Bendy': {
+    'hash': 44884,
+    'name': 'Burnable_Root_Hanging_Bendy',
+    'embedded': {
+      'Burnable_Root_Hanging_Bendy_46884': {
+        'hash': 46884,
+        'name': 'Burnable_Root_Hanging_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Hanging_Column_01': {
+    'hash': 39694,
+    'name': 'Burnable_Root_Hanging_Column_01',
+    'embedded': {
+      'Burnable_Root_Hanging_Column_01_43274': {
+        'hash': 43274,
+        'name': 'Burnable_Root_Hanging_Column_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Hanging_Column_02': {
+    'hash': 14166,
+    'name': 'Burnable_Root_Hanging_Column_02',
+    'embedded': {
+      'Burnable_Root_Hanging_Column_02_16140': {
+        'hash': 16140,
+        'name': 'Burnable_Root_Hanging_Column_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Hanging_Straight': {
+    'hash': 39592,
+    'name': 'Burnable_Root_Hanging_Straight',
+    'embedded': {
+      'Burnable_Root_Hanging_Straight_41518': {
+        'hash': 41518,
+        'name': 'Burnable_Root_Hanging_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Hanging_Thin_Bendy': {
+    'hash': 64866,
+    'name': 'Burnable_Root_Hanging_Thin_Bendy',
+    'embedded': {
+      'Burnable_Root_Hanging_Thin_Bendy_1566': {
+        'hash': 1566,
+        'name': 'Burnable_Root_Hanging_Thin_Bendy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Hanging_Thin_Straight': {
+    'hash': 36356,
+    'name': 'Burnable_Root_Hanging_Thin_Straight',
+    'embedded': {
+      'Burnable_Root_Hanging_Thin_Straight_38530': {
+        'hash': 38530,
+        'name': 'Burnable_Root_Hanging_Thin_Straight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Mound_Large': {
+    'hash': 48874,
+    'name': 'Burnable_Root_Mound_Large',
+    'embedded': {
+      'Burnable_Root_Mound_Large_15598': {
+        'hash': 15598,
+        'name': 'Burnable_Root_Mound_Large',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_Root_Mound_Small': {
+    'hash': 17066,
+    'name': 'Burnable_Root_Mound_Small',
+    'embedded': {
+      'Burnable_Root_Mound_Small_17070': {
+        'hash': 17070,
+        'name': 'Burnable_Root_Mound_Small',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_VineBunch': {
+    'hash': 35828,
+    'name': 'Burnable_VineBunch',
+    'embedded': {
+      'Burnable_VineBunch_35834': {
+        'hash': 35834,
+        'name': 'Burnable_VineBunch',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Burnable_VineBunch_Tutorial': {
+    'hash': 38202,
+    'name': 'Burnable_VineBunch_Tutorial',
+    'embedded': {
+      'Burnable_VineBunch_Tutorial_35834': {
+        'hash': 35834,
+        'name': 'Burnable_VineBunch_Tutorial',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Button_Spawner': {
+    'hash': 42752,
+    'name': 'Button_Spawner',
+    'embedded': {}
+  },
+  'Campfire': {
+    'hash': 63848,
+    'name': 'Campfire',
+    'embedded': {
+      'Campfire_8496': {
+        'hash': 8496,
+        'name': 'Campfire',
+        'savables': {}
+      },
+      'Fire_8488': {
+        'hash': 8488,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Campfire_Infinite': {
+    'hash': 63034,
+    'name': 'Campfire_Infinite',
+    'embedded': {
+      'Campfire_Infinite_8496': {
+        'hash': 8496,
+        'name': 'Campfire_Infinite',
+        'savables': {}
+      }
+    }
+  },
+  'Campfire_Spawner': {
+    'hash': 6584,
+    'name': 'Campfire_Spawner',
+    'embedded': {
+      'Campfire_Spawner_55752': {
+        'hash': 55752,
+        'name': 'Campfire_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Tinder_Spawner_64618': {
+        'hash': 64618,
+        'name': 'Tinder_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Campfire_Weak': {
+    'hash': 9276,
+    'name': 'Campfire_Weak',
+    'embedded': {
+      'Campfire_Weak_8496': {
+        'hash': 8496,
+        'name': 'Campfire_Weak',
+        'savables': {}
+      },
+      'Fire_8488': {
+        'hash': 8488,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Candy_Cane': {
+    'hash': 27314,
+    'name': 'Candy_Cane',
+    'embedded': {
+      'Candy_Cane_24532': {
+        'hash': 24532,
+        'name': 'Candy_Cane',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Candy_Cane_Knife_Spawner_3782': {
+        'hash': 3782,
+        'name': 'Candy_Cane_Knife_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Candy_Cane_Knife': {
+    'hash': 7676,
+    'name': 'Candy_Cane_Knife',
+    'embedded': {
+      'Candy_Cane_Knife_24532': {
+        'hash': 24532,
+        'name': 'Candy_Cane_Knife',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Full_Burnt': {
+    'hash': 62634,
+    'name': 'Carrot_Full_Burnt',
+    'embedded': {
+      'Carrot_Full_Burnt_61108': {
+        'hash': 61108,
+        'name': 'Carrot_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_3266': {
+        'hash': 3266,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Full_Cooked': {
+    'hash': 60742,
+    'name': 'Carrot_Full_Cooked',
+    'embedded': {
+      'Carrot_Full_Cooked_59204': {
+        'hash': 59204,
+        'name': 'Carrot_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_1986': {
+        'hash': 1986,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Full_Ripe': {
+    'hash': 58838,
+    'name': 'Carrot_Full_Ripe',
+    'embedded': {
+      'Carrot_Full_Ripe_57300': {
+        'hash': 57300,
+        'name': 'Carrot_Full_Ripe',
+        'savables': {
+          'BuildupPickup': {
+            'hash': 3373651539,
+            'name': 'BuildupPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_706': {
+        'hash': 706,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Leaves_Parent_29566': {
+        'hash': 29566,
+        'name': 'Leaves_Parent',
+        'savables': {}
+      }
+    }
+  },
+  'Carrot_Full_Unripe': {
+    'hash': 56934,
+    'name': 'Carrot_Full_Unripe',
+    'embedded': {
+      'Carrot_Full_Unripe_55396': {
+        'hash': 55396,
+        'name': 'Carrot_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_64962': {
+        'hash': 64962,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Half_Burnt': {
+    'hash': 64146,
+    'name': 'Carrot_Half_Burnt',
+    'embedded': {
+      'Carrot_Half_Burnt_63824': {
+        'hash': 63824,
+        'name': 'Carrot_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_38970': {
+        'hash': 38970,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Half_Cooked': {
+    'hash': 63758,
+    'name': 'Carrot_Half_Cooked',
+    'embedded': {
+      'Carrot_Half_Cooked_63420': {
+        'hash': 63420,
+        'name': 'Carrot_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_38624': {
+        'hash': 38624,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Half_Ripe': {
+    'hash': 63354,
+    'name': 'Carrot_Half_Ripe',
+    'embedded': {
+      'Carrot_Half_Ripe_63016': {
+        'hash': 63016,
+        'name': 'Carrot_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_38278': {
+        'hash': 38278,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Half_Unripe': {
+    'hash': 62950,
+    'name': 'Carrot_Half_Unripe',
+    'embedded': {
+      'Carrot_Half_Unripe_62612': {
+        'hash': 62612,
+        'name': 'Carrot_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Cooking_37932': {
+        'hash': 37932,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carrot_Leaves': {
+    'hash': 10440,
+    'name': 'Carrot_Leaves',
+    'embedded': {
+      'Carrot_Leaves_14888': {
+        'hash': 14888,
+        'name': 'Carrot_Leaves',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'PullPickup_32134': {
+        'hash': 32134,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Carsi_Ingot': {
+    'hash': 60868,
+    'name': 'Carsi_Ingot',
+    'embedded': {
+      'Carsi_Ingot_32738': {
+        'hash': 32738,
+        'name': 'Carsi_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_12680': {
+        'hash': 12680,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Carved_Pumpkin_Smelter': {
+    'hash': 27322,
+    'name': 'Carved_Pumpkin_Smelter',
+    'embedded': {
+      'Carved_Pumpkin_Smelter_24226': {
+        'hash': 24226,
+        'name': 'Carved_Pumpkin_Smelter',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Fire_30100': {
+        'hash': 30100,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Cast_Iron_Lamp': {
+    'hash': 24782,
+    'name': 'Cast_Iron_Lamp',
+    'embedded': {
+      'Cast_Iron_Lamp_48448': {
+        'hash': 48448,
+        'name': 'Cast_Iron_Lamp',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Fire_30100': {
+        'hash': 30100,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Cauldron_Medium': {
+    'hash': 45082,
+    'name': 'Cauldron_Medium',
+    'embedded': {
+      'Cauldron_Medium_42440': {
+        'hash': 42440,
+        'name': 'Cauldron_Medium',
+        'savables': {
+          'CookingPot': {
+            'hash': 2882590463,
+            'name': 'CookingPot'
+          },
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          },
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StewManager': {
+            'hash': 1499506132,
+            'name': 'StewManager'
+          }
+        }
+      },
+      'Handle_Top_20': {
+        'hash': 20,
+        'name': 'Handle_Top',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Heat_47560': {
+        'hash': 47560,
+        'name': 'Heat',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Liquid_19522': {
+        'hash': 19522,
+        'name': 'Liquid',
+        'savables': {}
+      },
+      'Top_of_Liquid_not_rotating_59824': {
+        'hash': 59824,
+        'name': 'Top_of_Liquid_not_rotating',
+        'savables': {}
+      },
+      'cookingPot_main_40': {
+        'hash': 40,
+        'name': 'cookingPot_main',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_medium_handle_L_grp_52': {
+        'hash': 52,
+        'name': 'cookingPot_medium_handle_L_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_medium_handle_R_grp_44': {
+        'hash': 44,
+        'name': 'cookingPot_medium_handle_R_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_01_24': {
+        'hash': 24,
+        'name': 'cookingPot_plate_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_02_28': {
+        'hash': 28,
+        'name': 'cookingPot_plate_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_03_36': {
+        'hash': 36,
+        'name': 'cookingPot_plate_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_04_32': {
+        'hash': 32,
+        'name': 'cookingPot_plate_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_mid_01_48': {
+        'hash': 48,
+        'name': 'cookingPot_plate_mid_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_mid_02_56': {
+        'hash': 56,
+        'name': 'cookingPot_plate_mid_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Cave_Explosion_Boulder': {
+    'hash': 31136,
+    'name': 'Cave_Explosion_Boulder',
+    'embedded': {
+      'Cave_Explosion_Boulder_31140': {
+        'hash': 31140,
+        'name': 'Cave_Explosion_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Cave_Explosion_Boulder_Clusters': {
+    'hash': 17608,
+    'name': 'Cave_Explosion_Boulder_Clusters',
+    'embedded': {
+      'Cave_Explosion_Boulder_Clusters_17602': {
+        'hash': 17602,
+        'name': 'Cave_Explosion_Boulder_Clusters',
+        'savables': {}
+      }
+    }
+  },
+  'Cave_Grass': {
+    'hash': 63846,
+    'name': 'Cave_Grass',
+    'embedded': {
+      'Cave_Grass_7194': {
+        'hash': 7194,
+        'name': 'Cave_Grass',
+        'savables': {}
+      },
+      'Fire_7186': {
+        'hash': 7186,
+        'name': 'Fire',
+        'savables': {
+          'FireDissolve': {
+            'hash': 3457519710,
+            'name': 'FireDissolve'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Cave_Layer_Chunk': {
+    'hash': 61672,
+    'name': 'Cave_Layer_Chunk',
+    'embedded': {}
+  },
+  'Cave_Layer_Generation': {
+    'hash': 61664,
+    'name': 'Cave_Layer_Generation',
+    'embedded': {}
+  },
+  'Cave_Surface_Teleporter_Ruins': {
+    'hash': 43368,
+    'name': 'Cave_Surface_Teleporter_Ruins',
+    'embedded': {}
+  },
+  'Cave_Teleporter': {
+    'hash': 27074,
+    'name': 'Cave_Teleporter',
+    'embedded': {}
+  },
+  'Cave_Teleporter_Station': {
+    'hash': 22840,
+    'name': 'Cave_Teleporter_Station',
+    'embedded': {}
+  },
+  'Cave_Teleporter_Station_Ruins': {
+    'hash': 29310,
+    'name': 'Cave_Teleporter_Station_Ruins',
+    'embedded': {}
+  },
+  'Cave_Wall_Support': {
+    'hash': 63840,
+    'name': 'Cave_Wall_Support',
+    'embedded': {
+      'Cave_Wall_Support_5636': {
+        'hash': 5636,
+        'name': 'Cave_Wall_Support',
+        'savables': {}
+      },
+      'Torch_Dock_5626': {
+        'hash': 5626,
+        'name': 'Torch_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Cave_Water_Mound': {
+    'hash': 57530,
+    'name': 'Cave_Water_Mound',
+    'embedded': {
+      'Cave_Water_Mound_57514': {
+        'hash': 57514,
+        'name': 'Cave_Water_Mound',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          }
+        }
+      },
+      'Heat_Point_52154': {
+        'hash': 52154,
+        'name': 'Heat_Point',
+        'savables': {}
+      },
+      'Mushroom_Spawn_Area_22970': {
+        'hash': 22970,
+        'name': 'Mushroom_Spawn_Area',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Wyrm_Spawn_Area_45512': {
+        'hash': 45512,
+        'name': 'Wyrm_Spawn_Area',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Ceiling_Lantern': {
+    'hash': 682,
+    'name': 'Ceiling_Lantern',
+    'embedded': {
+      'Ceiling_Lantern_684': {
+        'hash': 684,
+        'name': 'Ceiling_Lantern',
+        'savables': {}
+      },
+      'ceilingLight_Light_jnt_48980': {
+        'hash': 48980,
+        'name': 'ceilingLight_Light_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'ceilingLight_arm_jnt_48984': {
+        'hash': 48984,
+        'name': 'ceilingLight_arm_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'ceilingLight_root_jnt_48976': {
+        'hash': 48976,
+        'name': 'ceilingLight_root_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Ceiling_Lantern_Lit': {
+    'hash': 32476,
+    'name': 'Ceiling_Lantern_Lit',
+    'embedded': {
+      'Ceiling_Lantern_Lit_684': {
+        'hash': 684,
+        'name': 'Ceiling_Lantern_Lit',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Fire_55870': {
+        'hash': 55870,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          }
+        }
+      },
+      'ceilingLight_Light_jnt_48980': {
+        'hash': 48980,
+        'name': 'ceilingLight_Light_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'ceilingLight_arm_jnt_48984': {
+        'hash': 48984,
+        'name': 'ceilingLight_arm_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'ceilingLight_root_jnt_48976': {
+        'hash': 48976,
+        'name': 'ceilingLight_root_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Ceiling_Light': {
+    'hash': 8226,
+    'name': 'Ceiling_Light',
+    'embedded': {
+      'Ceiling_Light_8232': {
+        'hash': 8232,
+        'name': 'Ceiling_Light',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Fire_54948': {
+        'hash': 54948,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'ceilingLight_Light_jnt_48980': {
+        'hash': 48980,
+        'name': 'ceilingLight_Light_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'ceilingLight_arm_jnt_48984': {
+        'hash': 48984,
+        'name': 'ceilingLight_arm_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'ceilingLight_root_jnt_48976': {
+        'hash': 48976,
+        'name': 'ceilingLight_root_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Character_Level_Stone': {
+    'hash': 60762,
+    'name': 'Character_Level_Stone',
+    'embedded': {
+      'Character_Level_Stone_57948': {
+        'hash': 57948,
+        'name': 'Character_Level_Stone',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'Landmark_Finder_24472': {
+        'hash': 24472,
+        'name': 'Landmark_Finder',
+        'savables': {
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_Bishop': {
+    'hash': 16998,
+    'name': 'Chess_Black_Bishop',
+    'embedded': {
+      'Chess_Black_Bishop_42198': {
+        'hash': 42198,
+        'name': 'Chess_Black_Bishop',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_Checker': {
+    'hash': 16378,
+    'name': 'Chess_Black_Checker',
+    'embedded': {
+      'Chess_Black_Checker_42196': {
+        'hash': 42196,
+        'name': 'Chess_Black_Checker',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_King': {
+    'hash': 17200,
+    'name': 'Chess_Black_King',
+    'embedded': {
+      'Chess_Black_King_42194': {
+        'hash': 42194,
+        'name': 'Chess_Black_King',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_Knight': {
+    'hash': 17291,
+    'name': 'Chess_Black_Knight',
+    'embedded': {
+      'Chess_Black_Knight_42200': {
+        'hash': 42200,
+        'name': 'Chess_Black_Knight',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_Pawn': {
+    'hash': 17282,
+    'name': 'Chess_Black_Pawn',
+    'embedded': {
+      'Chess_Black_Pawn_42202': {
+        'hash': 42202,
+        'name': 'Chess_Black_Pawn',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_Queen': {
+    'hash': 16204,
+    'name': 'Chess_Black_Queen',
+    'embedded': {
+      'Chess_Black_Queen_42192': {
+        'hash': 42192,
+        'name': 'Chess_Black_Queen',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Black_Rook': {
+    'hash': 16142,
+    'name': 'Chess_Black_Rook',
+    'embedded': {
+      'Chess_Black_Rook_42196': {
+        'hash': 42196,
+        'name': 'Chess_Black_Rook',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_Board': {
+    'hash': 16896,
+    'name': 'Chess_Board',
+    'embedded': {
+      'Chess_Board_24184': {
+        'hash': 24184,
+        'name': 'Chess_Board',
+        'savables': {
+          'GhostSnapSlotCollection': {
+            'hash': 1823429789,
+            'name': 'GhostSnapSlotCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_Bishop': {
+    'hash': 17162,
+    'name': 'Chess_White_Bishop',
+    'embedded': {
+      'Chess_White_Bishop_42198': {
+        'hash': 42198,
+        'name': 'Chess_White_Bishop',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_Checker': {
+    'hash': 16326,
+    'name': 'Chess_White_Checker',
+    'embedded': {
+      'Chess_White_Checker_42196': {
+        'hash': 42196,
+        'name': 'Chess_White_Checker',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_King': {
+    'hash': 16276,
+    'name': 'Chess_White_King',
+    'embedded': {
+      'Chess_White_King_42194': {
+        'hash': 42194,
+        'name': 'Chess_White_King',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_Knight': {
+    'hash': 17038,
+    'name': 'Chess_White_Knight',
+    'embedded': {
+      'Chess_White_Knight_42200': {
+        'hash': 42200,
+        'name': 'Chess_White_Knight',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_Pawn': {
+    'hash': 17240,
+    'name': 'Chess_White_Pawn',
+    'embedded': {
+      'Chess_White_Pawn_42202': {
+        'hash': 42202,
+        'name': 'Chess_White_Pawn',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_Queen': {
+    'hash': 16246,
+    'name': 'Chess_White_Queen',
+    'embedded': {
+      'Chess_White_Queen_42192': {
+        'hash': 42192,
+        'name': 'Chess_White_Queen',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chess_White_Rook': {
+    'hash': 17084,
+    'name': 'Chess_White_Rook',
+    'embedded': {
+      'Chess_White_Rook_42196': {
+        'hash': 42196,
+        'name': 'Chess_White_Rook',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chisel': {
+    'hash': 44380,
+    'name': 'Chisel',
+    'embedded': {
+      'Chisel_48634': {
+        'hash': 48634,
+        'name': 'Chisel',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_64518': {
+        'hash': 64518,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_25524': {
+        'hash': 25524,
+        'name': 'Insert_SwordType',
+        'savables': {}
+      },
+      'metal_chisel_blade_full_geo_LOD0_48424': {
+        'hash': 48424,
+        'name': 'metal_chisel_blade_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'ChiselDeck': {
+    'hash': 37398,
+    'name': 'ChiselDeck',
+    'embedded': {
+      'ChiselDeck_50854': {
+        'hash': 50854,
+        'name': 'ChiselDeck',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'ChisellingDeck': {
+            'hash': 3236280681,
+            'name': 'ChisellingDeck'
+          },
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          }
+        }
+      },
+      'ChiselDeck_SetBlock_grp_63040': {
+        'hash': 63040,
+        'name': 'ChiselDeck_SetBlock_grp',
+        'savables': {}
+      },
+      'Docker_11728': {
+        'hash': 11728,
+        'name': 'Docker',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'leftHandle_grip_41084': {
+        'hash': 41084,
+        'name': 'leftHandle_grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'panelSwivel_slotFrame_29114': {
+        'hash': 29114,
+        'name': 'panelSwivel_slotFrame',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'rightHandle_grip_41080': {
+        'hash': 41080,
+        'name': 'rightHandle_grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'rotateHandleGrip_22918': {
+        'hash': 22918,
+        'name': 'rotateHandleGrip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Chocolate_Easter_Egg': {
+    'hash': 30164,
+    'name': 'Chocolate_Easter_Egg',
+    'embedded': {
+      'Chocolate_Easter_Egg_30160': {
+        'hash': 30160,
+        'name': 'Chocolate_Easter_Egg',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Christmas_Gift_Box': {
+    'hash': 17920,
+    'name': 'Christmas_Gift_Box',
+    'embedded': {
+      'Christmas_Gift_Box_17050': {
+        'hash': 17050,
+        'name': 'Christmas_Gift_Box',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Content_40226': {
+        'hash': 40226,
+        'name': 'Spawn_Content',
+        'savables': {}
+      }
+    }
+  },
+  'Christmas_Gift_Box_Spawner': {
+    'hash': 63174,
+    'name': 'Christmas_Gift_Box_Spawner',
+    'embedded': {
+      'Christmas_Gift_Box_Spawner_42278': {
+        'hash': 42278,
+        'name': 'Christmas_Gift_Box_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Christmas_Gift_Box_Special': {
+    'hash': 18144,
+    'name': 'Christmas_Gift_Box_Special',
+    'embedded': {
+      'Christmas_Gift_Box_Special_17050': {
+        'hash': 17050,
+        'name': 'Christmas_Gift_Box_Special',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Content_40226': {
+        'hash': 40226,
+        'name': 'Spawn_Content',
+        'savables': {}
+      }
+    }
+  },
+  'Christmas_Gift_Mail_Box_01': {
+    'hash': 24764,
+    'name': 'Christmas_Gift_Mail_Box_01',
+    'embedded': {
+      'Christmas_Gift_Mail_Box_01_17050': {
+        'hash': 17050,
+        'name': 'Christmas_Gift_Mail_Box_01',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'SentGift': {
+            'hash': 661497638,
+            'name': 'SentGift'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Christmas_Gift_Mail_Box_02': {
+    'hash': 16494,
+    'name': 'Christmas_Gift_Mail_Box_02',
+    'embedded': {
+      'Christmas_Gift_Mail_Box_02_17050': {
+        'hash': 17050,
+        'name': 'Christmas_Gift_Mail_Box_02',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'SentGift': {
+            'hash': 661497638,
+            'name': 'SentGift'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Christmas_Gift_Mail_Box_03': {
+    'hash': 1080,
+    'name': 'Christmas_Gift_Mail_Box_03',
+    'embedded': {
+      'Christmas_Gift_Mail_Box_03_17050': {
+        'hash': 17050,
+        'name': 'Christmas_Gift_Mail_Box_03',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'SentGift': {
+            'hash': 661497638,
+            'name': 'SentGift'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Christmas_Tree': {
+    'hash': 56318,
+    'name': 'Christmas_Tree',
+    'embedded': {
+      'Christmas_Tree_15640': {
+        'hash': 15640,
+        'name': 'Christmas_Tree',
+        'savables': {}
+      }
+    }
+  },
+  'Chunk_Directional_Surface': {
+    'hash': 47534,
+    'name': 'Chunk_Directional_Surface',
+    'embedded': {}
+  },
+  'Chunk_Spherical_Surface': {
+    'hash': 47614,
+    'name': 'Chunk_Spherical_Surface',
+    'embedded': {}
+  },
+  'Chute_Gcore_Dynamic': {
+    'hash': 60246,
+    'name': 'Chute_Gcore_Dynamic',
+    'embedded': {
+      'Chute_Gcore_Dynamic_53304': {
+        'hash': 53304,
+        'name': 'Chute_Gcore_Dynamic',
+        'savables': {}
+      },
+      'Complete_63570': {
+        'hash': 63570,
+        'name': 'Complete',
+        'savables': {}
+      },
+      'Diggable_4216': {
+        'hash': 4216,
+        'name': 'Diggable',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Enemy_Spawn_12232': {
+        'hash': 12232,
+        'name': 'Enemy_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Erupt_Area_2920': {
+        'hash': 2920,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Erupt_Area_3280': {
+        'hash': 3280,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Erupt_Area_3286': {
+        'hash': 3286,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Erupt_Area_3486': {
+        'hash': 3486,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Geyser_AI_2664': {
+        'hash': 2664,
+        'name': 'Geyser_AI',
+        'savables': {}
+      },
+      'Geyser_AI_2944': {
+        'hash': 2944,
+        'name': 'Geyser_AI',
+        'savables': {}
+      },
+      'Geyser_AI_2946': {
+        'hash': 2946,
+        'name': 'Geyser_AI',
+        'savables': {}
+      },
+      'Geyser_AI_29794': {
+        'hash': 29794,
+        'name': 'Geyser_AI',
+        'savables': {}
+      },
+      'Geyser_AI_3258': {
+        'hash': 3258,
+        'name': 'Geyser_AI',
+        'savables': {}
+      },
+      'Reset_63566': {
+        'hash': 63566,
+        'name': 'Reset',
+        'savables': {}
+      },
+      'Targeted_Geyser_(1)_27232': {
+        'hash': 27232,
+        'name': 'Targeted_Geyser_(1)',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Targeted_Geyser_(2)_27100': {
+        'hash': 27100,
+        'name': 'Targeted_Geyser_(2)',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Targeted_Geyser_(3)_26416': {
+        'hash': 26416,
+        'name': 'Targeted_Geyser_(3)',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Targeted_Geyser_(4)_26284': {
+        'hash': 26284,
+        'name': 'Targeted_Geyser_(4)',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Targeted_Geyser_(5)_25600': {
+        'hash': 25600,
+        'name': 'Targeted_Geyser_(5)',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Top_Enemy_Spawn_12202': {
+        'hash': 12202,
+        'name': 'Top_Enemy_Spawn',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'CircleSpawner': {
+    'hash': 49642,
+    'name': 'CircleSpawner',
+    'embedded': {
+      'CircleSpawner_52610': {
+        'hash': 52610,
+        'name': 'CircleSpawner',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SpawnInCircle': {
+            'hash': 1714180166,
+            'name': 'SpawnInCircle'
+          }
+        }
+      }
+    }
+  },
+  'CircleSpawner(ExplosiveSpike)': {
+    'hash': 31046,
+    'name': 'CircleSpawner(ExplosiveSpike)',
+    'embedded': {
+      'CircleSpawner(ExplosiveSpike)_52620': {
+        'hash': 52620,
+        'name': 'CircleSpawner(ExplosiveSpike)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SpawnInCircle': {
+            'hash': 1714180166,
+            'name': 'SpawnInCircle'
+          }
+        }
+      }
+    }
+  },
+  'CircleSpawner_ExplosiveSpike': {
+    'hash': 31046,
+    'name': 'CircleSpawner_ExplosiveSpike',
+    'embedded': {}
+  },
+  'Climbing_Tower_Progression_Visualizer': {
+    'hash': 44244,
+    'name': 'Climbing_Tower_Progression_Visualizer',
+    'embedded': {
+      'Climbing_Tower_Progression_Visualizer_43852': {
+        'hash': 43852,
+        'name': 'Climbing_Tower_Progression_Visualizer',
+        'savables': {
+          'ClimbingTowerProgressionVisualizer': {
+            'hash': 623957243,
+            'name': 'ClimbingTowerProgressionVisualizer'
+          }
+        }
+      },
+      'Ruins_Hand_Touch_Activator_20982': {
+        'hash': 20982,
+        'name': 'Ruins_Hand_Touch_Activator',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  'Climbing_Unlock_Orb_Pedestal': {
+    'hash': 51594,
+    'name': 'Climbing_Unlock_Orb_Pedestal',
+    'embedded': {
+      'Climbing_Unlock_Orb_Pedestal_51198': {
+        'hash': 51198,
+        'name': 'Climbing_Unlock_Orb_Pedestal',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {
+          'AddUnlockToPlayer': {
+            'hash': 1756836969,
+            'name': 'AddUnlockToPlayer'
+          },
+          'ClimbingTowerTeleporterNode': {
+            'hash': 392234266,
+            'name': 'ClimbingTowerTeleporterNode'
+          },
+          'OrbBasinVfxController': {
+            'hash': 715394364,
+            'name': 'OrbBasinVfxController'
+          },
+          'PlayerUnlockStation': {
+            'hash': 2912807649,
+            'name': 'PlayerUnlockStation'
+          }
+        }
+      }
+    }
+  },
+  'Coal': {
+    'hash': 19658,
+    'name': 'Coal',
+    'embedded': {
+      'Coal_19542': {
+        'hash': 19542,
+        'name': 'Coal',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Coal_Ash': {
+    'hash': 2792,
+    'name': 'Coal_Ash',
+    'embedded': {
+      'Coal_Ash_2796': {
+        'hash': 2796,
+        'name': 'Coal_Ash',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Coal_Boulder_01': {
+    'hash': 23502,
+    'name': 'Coal_Boulder_01',
+    'embedded': {
+      'Coal_Boulder_01_23506': {
+        'hash': 23506,
+        'name': 'Coal_Boulder_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Coal_Boulder_02': {
+    'hash': 57382,
+    'name': 'Coal_Boulder_02',
+    'embedded': {
+      'Coal_Boulder_02_57386': {
+        'hash': 57386,
+        'name': 'Coal_Boulder_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Coal_Boulder_03': {
+    'hash': 23788,
+    'name': 'Coal_Boulder_03',
+    'embedded': {
+      'Coal_Boulder_03_23792': {
+        'hash': 23792,
+        'name': 'Coal_Boulder_03',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Coal_Training': {
+    'hash': 51610,
+    'name': 'Coal_Training',
+    'embedded': {
+      'Coal_Training_51606': {
+        'hash': 51606,
+        'name': 'Coal_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Coin_Press': {
+    'hash': 31306,
+    'name': 'Coin_Press',
+    'embedded': {
+      'Coin_Press_65312': {
+        'hash': 65312,
+        'name': 'Coin_Press',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Input_36080': {
+        'hash': 36080,
+        'name': 'Input',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Lever_Physics_45996': {
+        'hash': 45996,
+        'name': 'Lever_Physics',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Output_52720': {
+        'hash': 52720,
+        'name': 'Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Concoction_Crate': {
+    'hash': 23304,
+    'name': 'Concoction_Crate',
+    'embedded': {
+      'Concoction_Crate_21538': {
+        'hash': 21538,
+        'name': 'Concoction_Crate',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          }
+        }
+      },
+      'Heat_Area_15578': {
+        'hash': 15578,
+        'name': 'Heat_Area',
+        'savables': {}
+      }
+    }
+  },
+  'Constant': {
+    'hash': 42424,
+    'name': 'Constant',
+    'embedded': {}
+  },
+  'Cooking_Stand': {
+    'hash': 6742,
+    'name': 'Cooking_Stand',
+    'embedded': {
+      'Cooking_Stand_51236': {
+        'hash': 51236,
+        'name': 'Cooking_Stand',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Crank_19094': {
+        'hash': 19094,
+        'name': 'Crank',
+        'savables': {}
+      },
+      'Handle_16064': {
+        'hash': 16064,
+        'name': 'Handle',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Hangable_Dock_5626': {
+        'hash': 5626,
+        'name': 'Hangable_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Long_S_Hook_17940': {
+        'hash': 17940,
+        'name': 'Long_S_Hook',
+        'savables': {}
+      }
+    }
+  },
+  'Copper_Boulder': {
+    'hash': 65380,
+    'name': 'Copper_Boulder',
+    'embedded': {
+      'Copper_Boulder_5600': {
+        'hash': 5600,
+        'name': 'Copper_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_38012': {
+        'hash': 38012,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Copper_Boulder_Parts': {
+    'hash': 46024,
+    'name': 'Copper_Boulder_Parts',
+    'embedded': {
+      'Copper_Boulder_Parts_4828': {
+        'hash': 4828,
+        'name': 'Copper_Boulder_Parts',
+        'savables': {}
+      },
+      'Copper_Boulder_part_01_4846': {
+        'hash': 4846,
+        'name': 'Copper_Boulder_part_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Copper_Boulder_part_02_13706': {
+        'hash': 13706,
+        'name': 'Copper_Boulder_part_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Copper_Boulder_part_03_13714': {
+        'hash': 13714,
+        'name': 'Copper_Boulder_part_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Copper_Boulder_part_04_13722': {
+        'hash': 13722,
+        'name': 'Copper_Boulder_part_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Copper_Boulder_part_05_13718': {
+        'hash': 13718,
+        'name': 'Copper_Boulder_part_05',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Copper_Cluster': {
+    'hash': 20646,
+    'name': 'Copper_Cluster',
+    'embedded': {
+      'Copper_Cluster_20644': {
+        'hash': 20644,
+        'name': 'Copper_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Copper_Ingot': {
+    'hash': 32850,
+    'name': 'Copper_Ingot',
+    'embedded': {
+      'Copper_Ingot_32738': {
+        'hash': 32738,
+        'name': 'Copper_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_12806': {
+        'hash': 12806,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Copper_Ore': {
+    'hash': 2484,
+    'name': 'Copper_Ore',
+    'embedded': {
+      'Copper_Ore_24090': {
+        'hash': 24090,
+        'name': 'Copper_Ore',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Craft_Piece_SideFlat_2Way': {
+    'hash': 26748,
+    'name': 'Craft_Piece_SideFlat_2Way',
+    'embedded': {
+      'Craft_Piece_SideFlat_2Way_24176': {
+        'hash': 24176,
+        'name': 'Craft_Piece_SideFlat_2Way',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_5256': {
+        'hash': 5256,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Edgetype_Craft_57508': {
+        'hash': 57508,
+        'name': 'Insert_Edgetype_Craft',
+        'savables': {}
+      },
+      'Slot_EdgeType_39368': {
+        'hash': 39368,
+        'name': 'Slot_EdgeType',
+        'savables': {}
+      },
+      'Slot_EdgeType_51672': {
+        'hash': 51672,
+        'name': 'Slot_EdgeType',
+        'savables': {}
+      },
+      'Slot_EdgeType_51674': {
+        'hash': 51674,
+        'name': 'Slot_EdgeType',
+        'savables': {}
+      },
+      'Slot_EdgeType_57506': {
+        'hash': 57506,
+        'name': 'Slot_EdgeType',
+        'savables': {}
+      }
+    }
+  },
+  'Craft_Piece_Side_1Way': {
+    'hash': 1274,
+    'name': 'Craft_Piece_Side_1Way',
+    'embedded': {
+      'Craft_Piece_Side_1Way_58156': {
+        'hash': 58156,
+        'name': 'Craft_Piece_Side_1Way',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_3876': {
+        'hash': 3876,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_AxeType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_AxeType_Craft',
+        'savables': {}
+      },
+      'Slot_AxeType_7170': {
+        'hash': 7170,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      }
+    }
+  },
+  'Craft_Piece_Side_2Way': {
+    'hash': 24046,
+    'name': 'Craft_Piece_Side_2Way',
+    'embedded': {
+      'Craft_Piece_Side_2Way_21146': {
+        'hash': 21146,
+        'name': 'Craft_Piece_Side_2Way',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_4164': {
+        'hash': 4164,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_AxeType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_AxeType_Craft',
+        'savables': {}
+      },
+      'Slot_AxeType_15316': {
+        'hash': 15316,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      },
+      'Slot_AxeType_15318': {
+        'hash': 15318,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      }
+    }
+  },
+  'Craft_Piece_Side_4Way': {
+    'hash': 32160,
+    'name': 'Craft_Piece_Side_4Way',
+    'embedded': {
+      'Craft_Piece_Side_4Way_30046': {
+        'hash': 30046,
+        'name': 'Craft_Piece_Side_4Way',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_4512': {
+        'hash': 4512,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_AxeType_Craft_15432': {
+        'hash': 15432,
+        'name': 'Insert_AxeType_Craft',
+        'savables': {}
+      },
+      'Slot_AxeType_17932': {
+        'hash': 17932,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      },
+      'Slot_AxeType_18636': {
+        'hash': 18636,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      },
+      'Slot_AxeType_19782': {
+        'hash': 19782,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      },
+      'Slot_AxeType_40654': {
+        'hash': 40654,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      }
+    }
+  },
+  'Craft_Piece_Side_Flat_1Way': {
+    'hash': 38606,
+    'name': 'Craft_Piece_Side_Flat_1Way',
+    'embedded': {
+      'Craft_Piece_Side_Flat_1Way_36346': {
+        'hash': 36346,
+        'name': 'Craft_Piece_Side_Flat_1Way',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_4868': {
+        'hash': 4868,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Edgetype_Craft_15580': {
+        'hash': 15580,
+        'name': 'Insert_Edgetype_Craft',
+        'savables': {}
+      },
+      'Slot_EdgeType_38338': {
+        'hash': 38338,
+        'name': 'Slot_EdgeType',
+        'savables': {}
+      },
+      'Slot_EdgeType_39368': {
+        'hash': 39368,
+        'name': 'Slot_EdgeType',
+        'savables': {}
+      }
+    }
+  },
+  'Crafting_Deck': {
+    'hash': 28396,
+    'name': 'Crafting_Deck',
+    'embedded': {
+      'Crafting_Deck_64040': {
+        'hash': 64040,
+        'name': 'Crafting_Deck',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'GenericCraftingStation': {
+            'hash': 766675725,
+            'name': 'GenericCraftingStation'
+          }
+        }
+      },
+      'Crafting_Deck_Crank_Handle_01_16064': {
+        'hash': 16064,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Crafting_Deck_Crank_Handle_02_19132': {
+        'hash': 19132,
+        'name': 'Crafting_Deck_Crank_Handle_02',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Crafting_Deck_Top_MOVE_25974': {
+        'hash': 25974,
+        'name': 'Crafting_Deck_Top_MOVE',
+        'savables': {}
+      },
+      'Crafting_Deck_top_ROTATE_21724': {
+        'hash': 21724,
+        'name': 'Crafting_Deck_top_ROTATE',
+        'savables': {}
+      },
+      'GameObject_47008': {
+        'hash': 47008,
+        'name': 'GameObject',
+        'savables': {}
+      },
+      'Page_Slot_29114': {
+        'hash': 29114,
+        'name': 'Page_Slot',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Crane_Center_Piece': {
+    'hash': 25456,
+    'name': 'Crane_Center_Piece',
+    'embedded': {
+      'Crane_Center_Piece_6864': {
+        'hash': 6864,
+        'name': 'Crane_Center_Piece',
+        'savables': {}
+      }
+    }
+  },
+  'Crank': {
+    'hash': 15392,
+    'name': 'Crank',
+    'embedded': {}
+  },
+  'Crate': {
+    'hash': 36180,
+    'name': 'Crate',
+    'embedded': {
+      'Crate_14764': {
+        'hash': 14764,
+        'name': 'Crate',
+        'savables': {
+          'GeneratedLoot': {
+            'hash': 3642863935,
+            'name': 'GeneratedLoot'
+          }
+        }
+      },
+      'Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_31842': {
+        'hash': 31842,
+        'name': 'Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_31266': {
+        'hash': 31266,
+        'name': 'Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_4_30878': {
+        'hash': 30878,
+        'name': 'Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Crate_Stack_Spawner': {
+    'hash': 38974,
+    'name': 'Crate_Stack_Spawner',
+    'embedded': {
+      'Crate_Stack_Spawner_14614': {
+        'hash': 14614,
+        'name': 'Crate_Stack_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Crater_Gcore_Dynamic': {
+    'hash': 21218,
+    'name': 'Crater_Gcore_Dynamic',
+    'embedded': {
+      'Crater_Gcore_Dynamic_53304': {
+        'hash': 53304,
+        'name': 'Crater_Gcore_Dynamic',
+        'savables': {}
+      },
+      'Enemy_Spawn_30256': {
+        'hash': 30256,
+        'name': 'Enemy_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Cross_Slash': {
+    'hash': 38008,
+    'name': 'Cross_Slash',
+    'embedded': {
+      'Cross_Slash_34552': {
+        'hash': 34552,
+        'name': 'Cross_Slash',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Blue': {
+    'hash': 38178,
+    'name': 'Crystal_Blue',
+    'embedded': {
+      'Crystal_Blue_40232': {
+        'hash': 40232,
+        'name': 'Crystal_Blue',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Blue_NoLight': {
+    'hash': 14778,
+    'name': 'Crystal_Blue_NoLight',
+    'embedded': {
+      'Crystal_Blue_NoLight_40232': {
+        'hash': 40232,
+        'name': 'Crystal_Blue_NoLight',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Cluster_Blue': {
+    'hash': 18096,
+    'name': 'Crystal_Cluster_Blue',
+    'embedded': {
+      'Crystal_Cluster_Blue_24556': {
+        'hash': 24556,
+        'name': 'Crystal_Cluster_Blue',
+        'savables': {}
+      }
+    }
+  },
+  'Crystal_Gem_Blue': {
+    'hash': 8002,
+    'name': 'Crystal_Gem_Blue',
+    'embedded': {
+      'Crystal_Gem_Blue_11514': {
+        'hash': 11514,
+        'name': 'Crystal_Gem_Blue',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Lance_Blue': {
+    'hash': 23400,
+    'name': 'Crystal_Lance_Blue',
+    'embedded': {
+      'Crystal_Lance_Blue_26000': {
+        'hash': 26000,
+        'name': 'Crystal_Lance_Blue',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Pick_Blue': {
+    'hash': 2924,
+    'name': 'Crystal_Pick_Blue',
+    'embedded': {
+      'Crystal_Pick_Blue_5368': {
+        'hash': 5368,
+        'name': 'Crystal_Pick_Blue',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Shard_Blue': {
+    'hash': 7092,
+    'name': 'Crystal_Shard_Blue',
+    'embedded': {
+      'Crystal_Shard_Blue_9072': {
+        'hash': 9072,
+        'name': 'Crystal_Shard_Blue',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Crystal_Structure_Blue': {
+    'hash': 51128,
+    'name': 'Crystal_Structure_Blue',
+    'embedded': {
+      'Crystal_Structure_Blue_54360': {
+        'hash': 54360,
+        'name': 'Crystal_Structure_Blue',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Structure_Rocks': {
+    'hash': 34144,
+    'name': 'Crystal_Structure_Rocks',
+    'embedded': {
+      'Crystal_Structure_Rocks_54772': {
+        'hash': 54772,
+        'name': 'Crystal_Structure_Rocks',
+        'savables': {}
+      }
+    }
+  },
+  'Crystal_Sword_Blue': {
+    'hash': 56894,
+    'name': 'Crystal_Sword_Blue',
+    'embedded': {
+      'Crystal_Sword_Blue_59644': {
+        'hash': 59644,
+        'name': 'Crystal_Sword_Blue',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Crystal_Wyrm': {
+    'hash': 37392,
+    'name': 'Crystal_Wyrm',
+    'embedded': {
+      'Animation_6144': {
+        'hash': 6144,
+        'name': 'Animation',
+        'savables': {}
+      },
+      'Body_1052': {
+        'hash': 1052,
+        'name': 'Body',
+        'savables': {}
+      },
+      'Crystal_Wyrm_37044': {
+        'hash': 37044,
+        'name': 'Crystal_Wyrm',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Crystal_Wyrm_AI_46146': {
+        'hash': 46146,
+        'name': 'Crystal_Wyrm_AI',
+        'savables': {}
+      },
+      'Gameplay_42330': {
+        'hash': 42330,
+        'name': 'Gameplay',
+        'savables': {}
+      },
+      'Ground_58968': {
+        'hash': 58968,
+        'name': 'Ground',
+        'savables': {}
+      },
+      'SlashDamage_L_57358': {
+        'hash': 57358,
+        'name': 'SlashDamage_L',
+        'savables': {}
+      },
+      'SlashDamage_R_59218': {
+        'hash': 59218,
+        'name': 'SlashDamage_R',
+        'savables': {}
+      },
+      'Spawner_240': {
+        'hash': 240,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'scythe_l_jnt_544': {
+        'hash': 544,
+        'name': 'scythe_l_jnt',
+        'savables': {}
+      },
+      'scythe_r_jnt_542': {
+        'hash': 542,
+        'name': 'scythe_r_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Crystal_Wyrm_(Trial)': {
+    'hash': 48128,
+    'name': 'Crystal_Wyrm_(Trial)',
+    'embedded': {
+      'Animation_6144': {
+        'hash': 6144,
+        'name': 'Animation',
+        'savables': {}
+      },
+      'Body_1052': {
+        'hash': 1052,
+        'name': 'Body',
+        'savables': {}
+      },
+      'Crystal_Wyrm_(Trial)_37044': {
+        'hash': 37044,
+        'name': 'Crystal_Wyrm_(Trial)',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Crystal_Wyrm_AI_46146': {
+        'hash': 46146,
+        'name': 'Crystal_Wyrm_AI',
+        'savables': {}
+      },
+      'Gameplay_42330': {
+        'hash': 42330,
+        'name': 'Gameplay',
+        'savables': {}
+      },
+      'Ground_58968': {
+        'hash': 58968,
+        'name': 'Ground',
+        'savables': {}
+      },
+      'SlashDamage_L_57358': {
+        'hash': 57358,
+        'name': 'SlashDamage_L',
+        'savables': {}
+      },
+      'SlashDamage_R_59218': {
+        'hash': 59218,
+        'name': 'SlashDamage_R',
+        'savables': {}
+      },
+      'Spawner_240': {
+        'hash': 240,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'scythe_l_jnt_544': {
+        'hash': 544,
+        'name': 'scythe_l_jnt',
+        'savables': {}
+      },
+      'scythe_r_jnt_542': {
+        'hash': 542,
+        'name': 'scythe_r_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Cube': {
+    'hash': 5262,
+    'name': 'Cube',
+    'embedded': {
+      'Cube_5268': {
+        'hash': 5268,
+        'name': 'Cube',
+        'savables': {}
+      }
+    }
+  },
+  'Curled_Wooden_Handle': {
+    'hash': 64172,
+    'name': 'Curled_Wooden_Handle',
+    'embedded': {
+      'Curled_Wooden_Handle_63962': {
+        'hash': 63962,
+        'name': 'Curled_Wooden_Handle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Dock_32818': {
+        'hash': 32818,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Slot_Multi_(1)_2108': {
+        'hash': 2108,
+        'name': 'Slot_Multi_(1)',
+        'savables': {}
+      },
+      'Slot_Multi_34270': {
+        'hash': 34270,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_34272': {
+        'hash': 34272,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Customization_Controller': {
+    'hash': 5526,
+    'name': 'Customization_Controller',
+    'embedded': {}
+  },
+  'Dagger_Blade_Curved': {
+    'hash': 9704,
+    'name': 'Dagger_Blade_Curved',
+    'embedded': {
+      'Dagger_Blade_Curved_35392': {
+        'hash': 35392,
+        'name': 'Dagger_Blade_Curved',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_64976': {
+        'hash': 64976,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'metal_blade_dagger_curved_LOD0_13424': {
+        'hash': 13424,
+        'name': 'metal_blade_dagger_curved_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Dagger_Blade_Edgy': {
+    'hash': 49402,
+    'name': 'Dagger_Blade_Edgy',
+    'embedded': {
+      'Dagger_Blade_Edgy_35392': {
+        'hash': 35392,
+        'name': 'Dagger_Blade_Edgy',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_65480': {
+        'hash': 65480,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'metal_blade_dagger_edgy_geo_LOD0_6500': {
+        'hash': 6500,
+        'name': 'metal_blade_dagger_edgy_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Dagger_Blade_Round': {
+    'hash': 56720,
+    'name': 'Dagger_Blade_Round',
+    'embedded': {
+      'Dagger_Blade_Round_35392': {
+        'hash': 35392,
+        'name': 'Dagger_Blade_Round',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_442': {
+        'hash': 442,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'metal_blade_dagger_round_full_geo_LOD0_22702': {
+        'hash': 22702,
+        'name': 'metal_blade_dagger_round_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Dagger_Blade_Wide': {
+    'hash': 54482,
+    'name': 'Dagger_Blade_Wide',
+    'embedded': {
+      'Dagger_Blade_Wide_54484': {
+        'hash': 54484,
+        'name': 'Dagger_Blade_Wide',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_926': {
+        'hash': 926,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'metal_blade_dagger_wide_full_geo_LOD0_53410': {
+        'hash': 53410,
+        'name': 'metal_blade_dagger_wide_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Dais_Antler_Red_Variant': {
+    'hash': 18358,
+    'name': 'Dais_Antler_Red_Variant',
+    'embedded': {
+      'Dais_AI_22350': {
+        'hash': 22350,
+        'name': 'Dais_AI',
+        'savables': {}
+      },
+      'Dais_Antler_Red_Variant_38050': {
+        'hash': 38050,
+        'name': 'Dais_Antler_Red_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Dais_Body_12508': {
+        'hash': 12508,
+        'name': 'Dais_Body',
+        'savables': {}
+      },
+      'Rare_Spawner_53168': {
+        'hash': 53168,
+        'name': 'Rare_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Dais_Antler_Variant': {
+    'hash': 30180,
+    'name': 'Dais_Antler_Variant',
+    'embedded': {
+      'Dais_AI_22350': {
+        'hash': 22350,
+        'name': 'Dais_AI',
+        'savables': {}
+      },
+      'Dais_Antler_Variant_38050': {
+        'hash': 38050,
+        'name': 'Dais_Antler_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Dais_Body_12508': {
+        'hash': 12508,
+        'name': 'Dais_Body',
+        'savables': {}
+      },
+      'Rare_Spawner_53168': {
+        'hash': 53168,
+        'name': 'Rare_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Dais_Child_Red_Variant': {
+    'hash': 13444,
+    'name': 'Dais_Child_Red_Variant',
+    'embedded': {
+      'Dais_AI_22350': {
+        'hash': 22350,
+        'name': 'Dais_AI',
+        'savables': {}
+      },
+      'Dais_Body_12508': {
+        'hash': 12508,
+        'name': 'Dais_Body',
+        'savables': {}
+      },
+      'Dais_Child_Red_Variant_38050': {
+        'hash': 38050,
+        'name': 'Dais_Child_Red_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Rare_Spawner_53168': {
+        'hash': 53168,
+        'name': 'Rare_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Dais_Child_Variant': {
+    'hash': 31838,
+    'name': 'Dais_Child_Variant',
+    'embedded': {
+      'Dais_AI_22350': {
+        'hash': 22350,
+        'name': 'Dais_AI',
+        'savables': {}
+      },
+      'Dais_Body_12508': {
+        'hash': 12508,
+        'name': 'Dais_Body',
+        'savables': {}
+      },
+      'Dais_Child_Variant_38050': {
+        'hash': 38050,
+        'name': 'Dais_Child_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Rare_Spawner_53168': {
+        'hash': 53168,
+        'name': 'Rare_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Dais_Meat_Full_Burnt': {
+    'hash': 41870,
+    'name': 'Dais_Meat_Full_Burnt',
+    'embedded': {
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Dais_Meat_Full_Burnt_47410': {
+        'hash': 47410,
+        'name': 'Dais_Meat_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Dais_Meat_Full_Cooked': {
+    'hash': 43452,
+    'name': 'Dais_Meat_Full_Cooked',
+    'embedded': {
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Dais_Meat_Full_Cooked_47410': {
+        'hash': 47410,
+        'name': 'Dais_Meat_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Dais_Meat_Full_Ripe': {
+    'hash': 47394,
+    'name': 'Dais_Meat_Full_Ripe',
+    'embedded': {
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Dais_Meat_Full_Ripe_42392': {
+        'hash': 42392,
+        'name': 'Dais_Meat_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Dais_Meat_Half_Burnt': {
+    'hash': 43674,
+    'name': 'Dais_Meat_Half_Burnt',
+    'embedded': {
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Dais_Meat_Half_Burnt_47410': {
+        'hash': 47410,
+        'name': 'Dais_Meat_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Dais_Meat_Half_Cooked': {
+    'hash': 43502,
+    'name': 'Dais_Meat_Half_Cooked',
+    'embedded': {
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Dais_Meat_Half_Cooked_47410': {
+        'hash': 47410,
+        'name': 'Dais_Meat_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Dais_Meat_Half_Ripe': {
+    'hash': 43294,
+    'name': 'Dais_Meat_Half_Ripe',
+    'embedded': {
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Dais_Meat_Half_Ripe_47410': {
+        'hash': 47410,
+        'name': 'Dais_Meat_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Dais_Red_Variant': {
+    'hash': 8530,
+    'name': 'Dais_Red_Variant',
+    'embedded': {
+      'Dais_AI_22350': {
+        'hash': 22350,
+        'name': 'Dais_AI',
+        'savables': {}
+      },
+      'Dais_Body_12508': {
+        'hash': 12508,
+        'name': 'Dais_Body',
+        'savables': {}
+      },
+      'Dais_Red_Variant_38050': {
+        'hash': 38050,
+        'name': 'Dais_Red_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Rare_Spawner_53168': {
+        'hash': 53168,
+        'name': 'Rare_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Dais_Variant': {
+    'hash': 42430,
+    'name': 'Dais_Variant',
+    'embedded': {
+      'Dais_AI_22350': {
+        'hash': 22350,
+        'name': 'Dais_AI',
+        'savables': {}
+      },
+      'Dais_Body_12508': {
+        'hash': 12508,
+        'name': 'Dais_Body',
+        'savables': {}
+      },
+      'Dais_Variant_38050': {
+        'hash': 38050,
+        'name': 'Dais_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Rare_Spawner_53168': {
+        'hash': 53168,
+        'name': 'Rare_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Darksteel_Ingot': {
+    'hash': 57556,
+    'name': 'Darksteel_Ingot',
+    'embedded': {}
+  },
+  'Death_Fern': {
+    'hash': 37642,
+    'name': 'Death_Fern',
+    'embedded': {
+      'Death_Fern_37626': {
+        'hash': 37626,
+        'name': 'Death_Fern',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Death_Fern_AI_29794': {
+        'hash': 29794,
+        'name': 'Death_Fern_AI',
+        'savables': {}
+      },
+      'Emit_Gas_Spawner_16984': {
+        'hash': 16984,
+        'name': 'Emit_Gas_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Death_Fern_Poison_Cloud': {
+    'hash': 39240,
+    'name': 'Death_Fern_Poison_Cloud',
+    'embedded': {
+      'Death_Fern_Poison_Cloud_50236': {
+        'hash': 50236,
+        'name': 'Death_Fern_Poison_Cloud',
+        'savables': {}
+      }
+    }
+  },
+  'Death_Fern_Seed_Planted': {
+    'hash': 40824,
+    'name': 'Death_Fern_Seed_Planted',
+    'embedded': {
+      'Death_Fern_Seed_Planted_40780': {
+        'hash': 40780,
+        'name': 'Death_Fern_Seed_Planted',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'DebugArrow': {
+    'hash': 34892,
+    'name': 'DebugArrow',
+    'embedded': {
+      'Arrow_Tip_59378': {
+        'hash': 59378,
+        'name': 'Arrow_Tip',
+        'savables': {}
+      },
+      'DebugArrow_43746': {
+        'hash': 43746,
+        'name': 'DebugArrow',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'DebugNet': {
+    'hash': 12632,
+    'name': 'DebugNet',
+    'embedded': {}
+  },
+  'DebugPlayerStone': {
+    'hash': 62120,
+    'name': 'DebugPlayerStone',
+    'embedded': {
+      'DebugPlayerStone_30920': {
+        'hash': 30920,
+        'name': 'DebugPlayerStone',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Primitive_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Primitive_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'DebugTool': {
+    'hash': 16078,
+    'name': 'DebugTool',
+    'embedded': {}
+  },
+  'Decrafting_Deck': {
+    'hash': 62244,
+    'name': 'Decrafting_Deck',
+    'embedded': {
+      'Decrafting_Deck_13304': {
+        'hash': 13304,
+        'name': 'Decrafting_Deck',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Lever_Physics_45996': {
+        'hash': 45996,
+        'name': 'Lever_Physics',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'TwoStepLever': {
+            'hash': 2213531414,
+            'name': 'TwoStepLever'
+          }
+        }
+      },
+      'Pickup_Holder_65018': {
+        'hash': 65018,
+        'name': 'Pickup_Holder',
+        'savables': {}
+      }
+    }
+  },
+  'Default_Burnt_Stew': {
+    'hash': 20108,
+    'name': 'Default_Burnt_Stew',
+    'embedded': {}
+  },
+  'Default_Cooked_Stew': {
+    'hash': 19398,
+    'name': 'Default_Cooked_Stew',
+    'embedded': {}
+  },
+  'Default_Raw_Stew': {
+    'hash': 43078,
+    'name': 'Default_Raw_Stew',
+    'embedded': {}
+  },
+  'Descent_Shaft_Gcore_Elevator_Dynamic': {
+    'hash': 52804,
+    'name': 'Descent_Shaft_Gcore_Elevator_Dynamic',
+    'embedded': {
+      'Crafting_Deck_Crank_Handle_01_16064': {
+        'hash': 16064,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Crafting_Deck_Crank_Handle_01_46520': {
+        'hash': 46520,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Crafting_Deck_Crank_Handle_01_60092': {
+        'hash': 60092,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Descent_Shaft_Gcore_Elevator_Dynamic_26570': {
+        'hash': 26570,
+        'name': 'Descent_Shaft_Gcore_Elevator_Dynamic',
+        'savables': {}
+      },
+      'Elevator_61068': {
+        'hash': 61068,
+        'name': 'Elevator',
+        'savables': {
+          'NetworkedFloatStream': {
+            'hash': 2127962967,
+            'name': 'NetworkedFloatStream'
+          }
+        }
+      }
+    }
+  },
+  'Descent_Shaft_Gcore_Floor_Diggable_Dynamic': {
+    'hash': 18120,
+    'name': 'Descent_Shaft_Gcore_Floor_Diggable_Dynamic',
+    'embedded': {
+      'Descent_Shaft_Gcore_Floor_Diggable_Dynamic_26570': {
+        'hash': 26570,
+        'name': 'Descent_Shaft_Gcore_Floor_Diggable_Dynamic',
+        'savables': {}
+      },
+      'Diggable_Spawner_2456': {
+        'hash': 2456,
+        'name': 'Diggable_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Descent_Shaft_Gcore_Floor_Mining_Boulder_Dynamic': {
+    'hash': 6308,
+    'name': 'Descent_Shaft_Gcore_Floor_Mining_Boulder_Dynamic',
+    'embedded': {
+      'Descent_Shaft_Gcore_Floor_Mining_Boulder_Dynamic_26570': {
+        'hash': 26570,
+        'name': 'Descent_Shaft_Gcore_Floor_Mining_Boulder_Dynamic',
+        'savables': {}
+      },
+      'Spawner_2456': {
+        'hash': 2456,
+        'name': 'Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Descent_Shaft_Gcore_Wall_Wyrm_Dynamic': {
+    'hash': 33338,
+    'name': 'Descent_Shaft_Gcore_Wall_Wyrm_Dynamic',
+    'embedded': {
+      'Descent_Shaft_Gcore_Wall_Wyrm_Dynamic_26570': {
+        'hash': 26570,
+        'name': 'Descent_Shaft_Gcore_Wall_Wyrm_Dynamic',
+        'savables': {}
+      },
+      'Spawner_36350': {
+        'hash': 36350,
+        'name': 'Spawner',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Digging_Box_Hebios': {
+    'hash': 42226,
+    'name': 'Digging_Box_Hebios',
+    'embedded': {
+      'Destroy_Effect_Spawner_61034': {
+        'hash': 61034,
+        'name': 'Destroy_Effect_Spawner',
+        'savables': {}
+      },
+      'Digging_Box_Hebios_43820': {
+        'hash': 43820,
+        'name': 'Digging_Box_Hebios',
+        'savables': {
+          'HealthBasedDigable': {
+            'hash': 2126500253,
+            'name': 'HealthBasedDigable'
+          }
+        }
+      },
+      'Spawn_Point_42650': {
+        'hash': 42650,
+        'name': 'Spawn_Point',
+        'savables': {}
+      }
+    }
+  },
+  'Digging_Dirt_Mound': {
+    'hash': 43924,
+    'name': 'Digging_Dirt_Mound',
+    'embedded': {
+      'Destroy_Effect_Spawner_61034': {
+        'hash': 61034,
+        'name': 'Destroy_Effect_Spawner',
+        'savables': {}
+      },
+      'Destroy_Gravestone_Spawner_40844': {
+        'hash': 40844,
+        'name': 'Destroy_Gravestone_Spawner',
+        'savables': {}
+      },
+      'Digging_Dirt_Mound_43820': {
+        'hash': 43820,
+        'name': 'Digging_Dirt_Mound',
+        'savables': {
+          'HealthBasedDigable': {
+            'hash': 2126500253,
+            'name': 'HealthBasedDigable'
+          }
+        }
+      },
+      'Spawn_Point_42650': {
+        'hash': 42650,
+        'name': 'Spawn_Point',
+        'savables': {}
+      },
+      'Stone_Spawner_6570': {
+        'hash': 6570,
+        'name': 'Stone_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Digging_Dirt_Mound_Hebios': {
+    'hash': 33570,
+    'name': 'Digging_Dirt_Mound_Hebios',
+    'embedded': {
+      'Destroy_Effect_Spawner_61034': {
+        'hash': 61034,
+        'name': 'Destroy_Effect_Spawner',
+        'savables': {}
+      },
+      'Destroy_Gravestone_Spawner_40844': {
+        'hash': 40844,
+        'name': 'Destroy_Gravestone_Spawner',
+        'savables': {}
+      },
+      'Digging_Dirt_Mound_Hebios_43820': {
+        'hash': 43820,
+        'name': 'Digging_Dirt_Mound_Hebios',
+        'savables': {
+          'HealthBasedDigable': {
+            'hash': 2126500253,
+            'name': 'HealthBasedDigable'
+          }
+        }
+      },
+      'Spawn_Point_42650': {
+        'hash': 42650,
+        'name': 'Spawn_Point',
+        'savables': {}
+      },
+      'Stone_Spawner_6570': {
+        'hash': 6570,
+        'name': 'Stone_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Digging_Dirt_Parts': {
+    'hash': 2538,
+    'name': 'Digging_Dirt_Parts',
+    'embedded': {
+      'Digging_Dirt_Parts_2554': {
+        'hash': 2554,
+        'name': 'Digging_Dirt_Parts',
+        'savables': {}
+      },
+      'digging_chunk_01_LOD0_2158': {
+        'hash': 2158,
+        'name': 'digging_chunk_01_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_02_LOD0_2166': {
+        'hash': 2166,
+        'name': 'digging_chunk_02_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_03_LOD0_2182': {
+        'hash': 2182,
+        'name': 'digging_chunk_03_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_04_LOD0_2164': {
+        'hash': 2164,
+        'name': 'digging_chunk_04_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_05_LOD0_2180': {
+        'hash': 2180,
+        'name': 'digging_chunk_05_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_06_LOD0_2178': {
+        'hash': 2178,
+        'name': 'digging_chunk_06_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_07_LOD0_2170': {
+        'hash': 2170,
+        'name': 'digging_chunk_07_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_08_LOD0_2168': {
+        'hash': 2168,
+        'name': 'digging_chunk_08_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_09_LOD0_2176': {
+        'hash': 2176,
+        'name': 'digging_chunk_09_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_10_LOD0_2174': {
+        'hash': 2174,
+        'name': 'digging_chunk_10_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_11_LOD0_2162': {
+        'hash': 2162,
+        'name': 'digging_chunk_11_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_12_LOD0_2160': {
+        'hash': 2160,
+        'name': 'digging_chunk_12_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'digging_chunk_13_LOD0_2172': {
+        'hash': 2172,
+        'name': 'digging_chunk_13_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Digging_Geode': {
+    'hash': 55696,
+    'name': 'Digging_Geode',
+    'embedded': {
+      'Destroy_Effect_Spawner_61034': {
+        'hash': 61034,
+        'name': 'Destroy_Effect_Spawner',
+        'savables': {}
+      },
+      'Digging_Geode_43820': {
+        'hash': 43820,
+        'name': 'Digging_Geode',
+        'savables': {
+          'HealthBasedDigable': {
+            'hash': 2126500253,
+            'name': 'HealthBasedDigable'
+          }
+        }
+      },
+      'Spawn_Point_42650': {
+        'hash': 42650,
+        'name': 'Spawn_Point',
+        'savables': {}
+      }
+    }
+  },
+  'Digging_Material_Box': {
+    'hash': 35612,
+    'name': 'Digging_Material_Box',
+    'embedded': {
+      'Destroy_Effect_Spawner_61034': {
+        'hash': 61034,
+        'name': 'Destroy_Effect_Spawner',
+        'savables': {}
+      },
+      'Digging_Material_Box_43820': {
+        'hash': 43820,
+        'name': 'Digging_Material_Box',
+        'savables': {
+          'HealthBasedDigable': {
+            'hash': 2126500253,
+            'name': 'HealthBasedDigable'
+          }
+        }
+      },
+      'Spawn_Point_42650': {
+        'hash': 42650,
+        'name': 'Spawn_Point',
+        'savables': {}
+      }
+    }
+  },
+  'Directional_Encounter': {
+    'hash': 23796,
+    'name': 'Directional_Encounter',
+    'embedded': {
+      /** @todo Verify entities and their components. */
+      'Directional_Encounter_43896': {
+        'hash': 43896,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Discovery_Landmark': {
+    'hash': 37940,
+    'name': 'Discovery_Landmark',
+    'embedded': {}
+  },
+  'Disk_Encounter': {
+    'hash': 65062,
+    'name': 'Disk_Encounter',
+    'embedded': {
+      /** @todo Verify entities and their components. */
+      'Disk_Encounter_43896': {
+        'hash': 43896,
+        'name': 'Disk_Encounter',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Dragonfly': {
+    'hash': 54404,
+    'name': 'Dragonfly',
+    'embedded': {
+      'Dragonfly_38050': {
+        'hash': 38050,
+        'name': 'Dragonfly',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Dragonfly_AI_22350': {
+        'hash': 22350,
+        'name': 'Dragonfly_AI',
+        'savables': {}
+      },
+      'Dragonfly_Body_7558': {
+        'hash': 7558,
+        'name': 'Dragonfly_Body',
+        'savables': {}
+      }
+    }
+  },
+  'Dragonfly_Corpse': {
+    'hash': 43552,
+    'name': 'Dragonfly_Corpse',
+    'embedded': {
+      'Dragonfly_Corpse_43536': {
+        'hash': 43536,
+        'name': 'Dragonfly_Corpse',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Drawbridge_Puzzle_Range': {
+    'hash': 40692,
+    'name': 'Drawbridge_Puzzle_Range',
+    'embedded': {
+      'Drawbridge_44588': {
+        'hash': 44588,
+        'name': 'Drawbridge',
+        'savables': {
+          'DrawBridgeRangeLogic': {
+            'hash': 2801168996,
+            'name': 'DrawBridgeRangeLogic'
+          }
+        }
+      },
+      'Drawbridge_Puzzle_Range_48230': {
+        'hash': 48230,
+        'name': 'Drawbridge_Puzzle_Range',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Drawbridge_Puzzle_Range_long': {
+    'hash': 58514,
+    'name': 'Drawbridge_Puzzle_Range_long',
+    'embedded': {
+      'Drawbridge_Puzzle_Range_long_62878': {
+        'hash': 62878,
+        'name': 'Drawbridge_Puzzle_Range_long',
+        'savables': {
+          'DrawBridgeRangeLogic': {
+            'hash': 2801168996,
+            'name': 'DrawBridgeRangeLogic'
+          },
+          'LinearPartCloner': {
+            'hash': 566175523,
+            'name': 'LinearPartCloner'
+          },
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Drawbridge_Puzzle_Toggle': {
+    'hash': 24580,
+    'name': 'Drawbridge_Puzzle_Toggle',
+    'embedded': {
+      'Drawbridge_Puzzle_Toggle_41872': {
+        'hash': 41872,
+        'name': 'Drawbridge_Puzzle_Toggle',
+        'savables': {
+          'DrawBridgeLogic': {
+            'hash': 2978042925,
+            'name': 'DrawBridgeLogic'
+          },
+          'DrawBridgeRangeLogic': {
+            'hash': 2801168996,
+            'name': 'DrawBridgeRangeLogic'
+          },
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Dried_Grass_Bush': {
+    'hash': 24480,
+    'name': 'Dried_Grass_Bush',
+    'embedded': {
+      'Dried_Grass_Bush_24440': {
+        'hash': 24440,
+        'name': 'Dried_Grass_Bush',
+        'savables': {}
+      }
+    }
+  },
+  'Dummy_Shelf_Short': {
+    'hash': 62404,
+    'name': 'Dummy_Shelf_Short',
+    'embedded': {
+      'Dock_58090': {
+        'hash': 58090,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dummy_Shelf_Short_60158': {
+        'hash': 60158,
+        'name': 'Dummy_Shelf_Short',
+        'savables': {}
+      }
+    }
+  },
+  'Duplicate_Paper_Variant': {
+    'hash': 11048,
+    'name': 'Duplicate_Paper_Variant',
+    'embedded': {}
+  },
+  'Dynamite': {
+    'hash': 31326,
+    'name': 'Dynamite',
+    'embedded': {
+      'Dynamite_40522': {
+        'hash': 40522,
+        'name': 'Dynamite',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Fuse_15214': {
+        'hash': 15214,
+        'name': 'Fuse',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'Fuse': {
+            'hash': 3665939353,
+            'name': 'Fuse'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Easter_Egg_01': {
+    'hash': 55462,
+    'name': 'Easter_Egg_01',
+    'embedded': {
+      'Easter_Egg_01_21224': {
+        'hash': 21224,
+        'name': 'Easter_Egg_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Easter_Egg_02': {
+    'hash': 57998,
+    'name': 'Easter_Egg_02',
+    'embedded': {
+      'Easter_Egg_02_28794': {
+        'hash': 28794,
+        'name': 'Easter_Egg_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Easter_Egg_03': {
+    'hash': 20128,
+    'name': 'Easter_Egg_03',
+    'embedded': {
+      'Easter_Egg_03_28794': {
+        'hash': 28794,
+        'name': 'Easter_Egg_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Easter_Egg_04': {
+    'hash': 21558,
+    'name': 'Easter_Egg_04',
+    'embedded': {
+      'Easter_Egg_04_28794': {
+        'hash': 28794,
+        'name': 'Easter_Egg_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Edge_Blade_Long_Curve': {
+    'hash': 17478,
+    'name': 'Edge_Blade_Long_Curve',
+    'embedded': {
+      'Edge_Blade_Long_Curve_15172': {
+        'hash': 15172,
+        'name': 'Edge_Blade_Long_Curve',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_5674': {
+        'hash': 5674,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Edgetype_7796': {
+        'hash': 7796,
+        'name': 'Insert_Edgetype',
+        'savables': {}
+      },
+      'edge_blade_longCurve_LOD0_22044': {
+        'hash': 22044,
+        'name': 'edge_blade_longCurve_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Edge_Curved_Blade': {
+    'hash': 11938,
+    'name': 'Edge_Curved_Blade',
+    'embedded': {
+      'Edge_Curved_Blade_9684': {
+        'hash': 9684,
+        'name': 'Edge_Curved_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_6064': {
+        'hash': 6064,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Edgetype_7796': {
+        'hash': 7796,
+        'name': 'Insert_Edgetype',
+        'savables': {}
+      },
+      'edge_blade_curved_LOD0_8062': {
+        'hash': 8062,
+        'name': 'edge_blade_curved_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Edge_Short_Curve_Blade': {
+    'hash': 20892,
+    'name': 'Edge_Short_Curve_Blade',
+    'embedded': {
+      'Edge_Short_Curve_Blade_18048': {
+        'hash': 18048,
+        'name': 'Edge_Short_Curve_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_6416': {
+        'hash': 6416,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Edgetype_7796': {
+        'hash': 7796,
+        'name': 'Insert_Edgetype',
+        'savables': {}
+      },
+      'edge_blade_shortCurve_LOD0_64382': {
+        'hash': 64382,
+        'name': 'edge_blade_shortCurve_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Edge_Straight_Blade': {
+    'hash': 30124,
+    'name': 'Edge_Straight_Blade',
+    'embedded': {
+      'Edge_Straight_Blade_27748': {
+        'hash': 27748,
+        'name': 'Edge_Straight_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_6764': {
+        'hash': 6764,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Edgetype_7796': {
+        'hash': 7796,
+        'name': 'Insert_Edgetype',
+        'savables': {}
+      },
+      'edge_blade_straight_LOD0_35880': {
+        'hash': 35880,
+        'name': 'edge_blade_straight_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Eggplant_Flower_Bloom': {
+    'hash': 27848,
+    'name': 'Eggplant_Flower_Bloom',
+    'embedded': {
+      'Eggplant_Flower_Bloom_42092': {
+        'hash': 42092,
+        'name': 'Eggplant_Flower_Bloom',
+        'savables': {}
+      }
+    }
+  },
+  'Eggplant_Flower_Bud': {
+    'hash': 27850,
+    'name': 'Eggplant_Flower_Bud',
+    'embedded': {
+      'Eggplant_Flower_Bud_42164': {
+        'hash': 42164,
+        'name': 'Eggplant_Flower_Bud',
+        'savables': {}
+      }
+    }
+  },
+  'Eggplant_Full_Burnt': {
+    'hash': 55030,
+    'name': 'Eggplant_Full_Burnt',
+    'embedded': {
+      'Cooking_29582': {
+        'hash': 29582,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Full_Burnt_54596': {
+        'hash': 54596,
+        'name': 'Eggplant_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Full_Cooked': {
+    'hash': 54506,
+    'name': 'Eggplant_Full_Cooked',
+    'embedded': {
+      'Cooking_29092': {
+        'hash': 29092,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Full_Cooked_54072': {
+        'hash': 54072,
+        'name': 'Eggplant_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Full_Ripe': {
+    'hash': 53982,
+    'name': 'Eggplant_Full_Ripe',
+    'embedded': {
+      'Cooking_28602': {
+        'hash': 28602,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Full_Ripe_53548': {
+        'hash': 53548,
+        'name': 'Eggplant_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Full_Unripe': {
+    'hash': 53458,
+    'name': 'Eggplant_Full_Unripe',
+    'embedded': {
+      'Cooking_28112': {
+        'hash': 28112,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Full_Unripe_53024': {
+        'hash': 53024,
+        'name': 'Eggplant_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Growth': {
+    'hash': 19304,
+    'name': 'Eggplant_Growth',
+    'embedded': {
+      'Eggplant_Growth_33458': {
+        'hash': 33458,
+        'name': 'Eggplant_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Half_Burnt': {
+    'hash': 62546,
+    'name': 'Eggplant_Half_Burnt',
+    'embedded': {
+      'Cooking_37586': {
+        'hash': 37586,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Half_Burnt_62208': {
+        'hash': 62208,
+        'name': 'Eggplant_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Half_Cooked': {
+    'hash': 62142,
+    'name': 'Eggplant_Half_Cooked',
+    'embedded': {
+      'Cooking_37240': {
+        'hash': 37240,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Half_Cooked_61804': {
+        'hash': 61804,
+        'name': 'Eggplant_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Half_Ripe': {
+    'hash': 61738,
+    'name': 'Eggplant_Half_Ripe',
+    'embedded': {
+      'Cooking_36894': {
+        'hash': 36894,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Half_Ripe_61400': {
+        'hash': 61400,
+        'name': 'Eggplant_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Half_Unripe': {
+    'hash': 61334,
+    'name': 'Eggplant_Half_Unripe',
+    'embedded': {
+      'Cooking_36548': {
+        'hash': 36548,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Eggplant_Half_Unripe_60996': {
+        'hash': 60996,
+        'name': 'Eggplant_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Potato_Recipe_Burnt_Stew': {
+    'hash': 57688,
+    'name': 'Eggplant_Potato_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Eggplant_Potato_Recipe_Cooked_Stew': {
+    'hash': 57712,
+    'name': 'Eggplant_Potato_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Eggplant_Potato_Recipe_Raw_Stew': {
+    'hash': 57736,
+    'name': 'Eggplant_Potato_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Eggplant_Tree': {
+    'hash': 27004,
+    'name': 'Eggplant_Tree',
+    'embedded': {
+      'Eggplant_Tree_24994': {
+        'hash': 24994,
+        'name': 'Eggplant_Tree',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Tree_Growth': {
+    'hash': 15090,
+    'name': 'Eggplant_Tree_Growth',
+    'embedded': {
+      'Eggplant_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Eggplant_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Tree_Separated': {
+    'hash': 17770,
+    'name': 'Eggplant_Tree_Separated',
+    'embedded': {}
+  },
+  'Eggplant_Tree_Stage_1': {
+    'hash': 14282,
+    'name': 'Eggplant_Tree_Stage_1',
+    'embedded': {
+      'Eggplant_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Eggplant_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Eggplant_Tree_Stage_2': {
+    'hash': 14440,
+    'name': 'Eggplant_Tree_Stage_2',
+    'embedded': {
+      'Eggplant_Tree_Stage_2_26756': {
+        'hash': 26756,
+        'name': 'Eggplant_Tree_Stage_2',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Eggplant_Tree_Stage_3': {
+    'hash': 16154,
+    'name': 'Eggplant_Tree_Stage_3',
+    'embedded': {
+      'Eggplant_Tree_Stage_3_22270': {
+        'hash': 22270,
+        'name': 'Eggplant_Tree_Stage_3',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Elevator': {
+    'hash': 44898,
+    'name': 'Elevator',
+    'embedded': {
+      'Crafting_Deck_Crank_Handle_01_16064': {
+        'hash': 16064,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Crafting_Deck_Crank_Handle_01_46520': {
+        'hash': 46520,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Elevator_26570': {
+        'hash': 26570,
+        'name': 'Elevator',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      }
+    }
+  },
+  'Elevator_Puzzle_Crank': {
+    'hash': 64134,
+    'name': 'Elevator_Puzzle_Crank',
+    'embedded': {
+      'Crafting_Deck_Crank_Handle_01_16064': {
+        'hash': 16064,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Crafting_Deck_Crank_Handle_01_46520': {
+        'hash': 46520,
+        'name': 'Crafting_Deck_Crank_Handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Elevator_26570': {
+        'hash': 26570,
+        'name': 'Elevator',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      },
+      'Elevator_Puzzle_Crank_52968': {
+        'hash': 52968,
+        'name': 'Elevator_Puzzle_Crank',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Elevator_Puzzle_Rope': {
+    'hash': 20484,
+    'name': 'Elevator_Puzzle_Rope',
+    'embedded': {
+      'Elevator_26570': {
+        'hash': 26570,
+        'name': 'Elevator',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      },
+      'Elevator_Puzzle_Rope_27070': {
+        'hash': 27070,
+        'name': 'Elevator_Puzzle_Rope',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Empty': {
+    'hash': 40954,
+    'name': 'Empty',
+    'embedded': {}
+  },
+  'Etheral_Arrow': {
+    'hash': 52366,
+    'name': 'Etheral_Arrow',
+    'embedded': {
+      'Etheral_Arrow_43746': {
+        'hash': 43746,
+        'name': 'Etheral_Arrow',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Spike_grp_58940': {
+        'hash': 58940,
+        'name': 'Spike_grp',
+        'savables': {}
+      }
+    }
+  },
+  'Evinon_Steel_Ingot': {
+    'hash': 32198,
+    'name': 'Evinon_Steel_Ingot',
+    'embedded': {
+      'Evinon_Steel_Ingot_32738': {
+        'hash': 32738,
+        'name': 'Evinon_Steel_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_12930': {
+        'hash': 12930,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Explosion_Boulder': {
+    'hash': 44162,
+    'name': 'Explosion_Boulder',
+    'embedded': {
+      'Explosion_Boulder_13178': {
+        'hash': 13178,
+        'name': 'Explosion_Boulder',
+        'savables': {
+          'ModifiableAdditionalStaticContent': {
+            'hash': 159391088,
+            'name': 'ModifiableAdditionalStaticContent'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Explosion_Boulder_Large': {
+    'hash': 30854,
+    'name': 'Explosion_Boulder_Large',
+    'embedded': {
+      'Explosion_Boulder_Large_30852': {
+        'hash': 30852,
+        'name': 'Explosion_Boulder_Large',
+        'savables': {
+          'ModifiableAdditionalStaticContent': {
+            'hash': 159391088,
+            'name': 'ModifiableAdditionalStaticContent'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Explosive_Spike': {
+    'hash': 50412,
+    'name': 'Explosive_Spike',
+    'embedded': {
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosive_Spike_15532': {
+        'hash': 15532,
+        'name': 'Explosive_Spike',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Fake_Player_combat_dummy': {
+    'hash': 45454,
+    'name': 'Fake_Player_combat_dummy',
+    'embedded': {
+      'Fake_Player_combat_dummy_57314': {
+        'hash': 57314,
+        'name': 'Fake_Player_combat_dummy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'dummy_arm_l_01_jnt_46272': {
+        'hash': 46272,
+        'name': 'dummy_arm_l_01_jnt',
+        'savables': {}
+      },
+      'dummy_arm_l_02_jnt_46248': {
+        'hash': 46248,
+        'name': 'dummy_arm_l_02_jnt',
+        'savables': {}
+      },
+      'dummy_arm_l_03_jnt_46250': {
+        'hash': 46250,
+        'name': 'dummy_arm_l_03_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_01_jnt_46246': {
+        'hash': 46246,
+        'name': 'dummy_arm_r_01_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_02_jnt_46254': {
+        'hash': 46254,
+        'name': 'dummy_arm_r_02_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_03_jnt_46256': {
+        'hash': 46256,
+        'name': 'dummy_arm_r_03_jnt',
+        'savables': {}
+      },
+      'dummy_head_01_jnt_46270': {
+        'hash': 46270,
+        'name': 'dummy_head_01_jnt',
+        'savables': {}
+      },
+      'dummy_head_02_jnt_46264': {
+        'hash': 46264,
+        'name': 'dummy_head_02_jnt',
+        'savables': {}
+      },
+      'dummy_head_03_jnt_46262': {
+        'hash': 46262,
+        'name': 'dummy_head_03_jnt',
+        'savables': {}
+      },
+      'dummy_neck_jnt_46268': {
+        'hash': 46268,
+        'name': 'dummy_neck_jnt',
+        'savables': {}
+      },
+      'dummy_spineMid_jnt_46274': {
+        'hash': 46274,
+        'name': 'dummy_spineMid_jnt',
+        'savables': {}
+      },
+      'dummy_spine_01_jnt_46258': {
+        'hash': 46258,
+        'name': 'dummy_spine_01_jnt',
+        'savables': {}
+      },
+      'dummy_spine_02_jnt_46260': {
+        'hash': 46260,
+        'name': 'dummy_spine_02_jnt',
+        'savables': {}
+      },
+      'dummy_spine_03_jnt_46266': {
+        'hash': 46266,
+        'name': 'dummy_spine_03_jnt',
+        'savables': {}
+      },
+      'dummy_sternum_jnt_46252': {
+        'hash': 46252,
+        'name': 'dummy_sternum_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Feather_Red_Training': {
+    'hash': 80,
+    'name': 'Feather_Red_Training',
+    'embedded': {
+      'Feather_Red_Training_74': {
+        'hash': 74,
+        'name': 'Feather_Red_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Firebug': {
+    'hash': 40478,
+    'name': 'Firebug',
+    'embedded': {
+      'Firebug_38050': {
+        'hash': 38050,
+        'name': 'Firebug',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Firebug_AI_22350': {
+        'hash': 22350,
+        'name': 'Firebug_AI',
+        'savables': {}
+      },
+      'firebug_7558': {
+        'hash': 7558,
+        'name': 'firebug',
+        'savables': {}
+      }
+    }
+  },
+  'Firework': {
+    'hash': 40748,
+    'name': 'Firework',
+    'embedded': {
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {
+          'ColoredExplosive': {
+            'hash': 3920618075,
+            'name': 'ColoredExplosive'
+          }
+        }
+      },
+      'Firework_40732': {
+        'hash': 40732,
+        'name': 'Firework',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      },
+      'Fuse__15214': {
+        'hash': 15214,
+        'name': 'Fuse_',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'Fuse': {
+            'hash': 3665939353,
+            'name': 'Fuse'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Fixed_Light_Bag_Attachment': {
+    'hash': 1056,
+    'name': 'Fixed_Light_Bag_Attachment',
+    'embedded': {
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'AdditionalOwnedDock': {
+            'hash': 2592242915,
+            'name': 'AdditionalOwnedDock'
+          }
+        }
+      },
+      'Fixed_Light_Bag_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Fixed_Light_Bag_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Insert_Bag_Tool_Attachment_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'Storage_38218': {
+        'hash': 38218,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'bag_lighting_attachment_pin_49786': {
+        'hash': 49786,
+        'name': 'bag_lighting_attachment_pin',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_ropeWrap_01_49802': {
+        'hash': 49802,
+        'name': 'bag_lighting_attachment_ropeWrap_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_ropeWrap_02_49798': {
+        'hash': 49798,
+        'name': 'bag_lighting_attachment_ropeWrap_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_rope_01_49778': {
+        'hash': 49778,
+        'name': 'bag_lighting_attachment_rope_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_rope_02_49774': {
+        'hash': 49774,
+        'name': 'bag_lighting_attachment_rope_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_rope_03_49770': {
+        'hash': 49770,
+        'name': 'bag_lighting_attachment_rope_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_stick_01_49794': {
+        'hash': 49794,
+        'name': 'bag_lighting_attachment_stick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_stick_02_49790': {
+        'hash': 49790,
+        'name': 'bag_lighting_attachment_stick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'bag_lighting_attachment_stick_03_49782': {
+        'hash': 49782,
+        'name': 'bag_lighting_attachment_stick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Flame_Step_Effect_Proto': {
+    'hash': 24020,
+    'name': 'Flame_Step_Effect_Proto',
+    'embedded': {
+      'Flame_Step_Effect_Proto_26204': {
+        'hash': 26204,
+        'name': 'Flame_Step_Effect_Proto',
+        'savables': {}
+      },
+      'Heating_Bit_26176': {
+        'hash': 26176,
+        'name': 'Heating_Bit',
+        'savables': {}
+      },
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Flame_Step_Effect_Proto_Lava_Test_Long_Variant': {
+    'hash': 54460,
+    'name': 'Flame_Step_Effect_Proto_Lava_Test_Long_Variant',
+    'embedded': {
+      'Flame_Step_Effect_Proto_Lava_Test_Long_Variant_63786': {
+        'hash': 63786,
+        'name': 'Flame_Step_Effect_Proto_Lava_Test_Long_Variant',
+        'savables': {}
+      },
+      'Heating_Bit_26176': {
+        'hash': 26176,
+        'name': 'Heating_Bit',
+        'savables': {}
+      },
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Flame_Step_Effect_Proto_Lava_Test_Variant': {
+    'hash': 41226,
+    'name': 'Flame_Step_Effect_Proto_Lava_Test_Variant',
+    'embedded': {
+      'Flame_Step_Effect_Proto_Lava_Test_Variant_63786': {
+        'hash': 63786,
+        'name': 'Flame_Step_Effect_Proto_Lava_Test_Variant',
+        'savables': {}
+      },
+      'Heating_Bit_26176': {
+        'hash': 26176,
+        'name': 'Heating_Bit',
+        'savables': {}
+      },
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Flame_Step_Effect_Proto_Vent_test': {
+    'hash': 5142,
+    'name': 'Flame_Step_Effect_Proto_Vent_test',
+    'embedded': {
+      'Flame_Step_Effect_Proto_Vent_test_10768': {
+        'hash': 10768,
+        'name': 'Flame_Step_Effect_Proto_Vent_test',
+        'savables': {}
+      },
+      'Heating_Bit_26176': {
+        'hash': 26176,
+        'name': 'Heating_Bit',
+        'savables': {}
+      },
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Flaming_Coalbed': {
+    'hash': 13480,
+    'name': 'Flaming_Coalbed',
+    'embedded': {
+      'Flaming_Coalbed_26204': {
+        'hash': 26204,
+        'name': 'Flaming_Coalbed',
+        'savables': {}
+      },
+      'Heating_Bit_26176': {
+        'hash': 26176,
+        'name': 'Heating_Bit',
+        'savables': {}
+      },
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Flashlight_Lantern': {
+    'hash': 23642,
+    'name': 'Flashlight_Lantern',
+    'embedded': {
+      'Fire_54948': {
+        'hash': 54948,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Flashlight_Lantern_23664': {
+        'hash': 23664,
+        'name': 'Flashlight_Lantern',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Fuel_Dock_63110': {
+        'hash': 63110,
+        'name': 'Fuel_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'flashlight_body_63430': {
+        'hash': 63430,
+        'name': 'flashlight_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_body_pin_01_63422': {
+        'hash': 63422,
+        'name': 'flashlight_body_pin_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_body_pin_02_63418': {
+        'hash': 63418,
+        'name': 'flashlight_body_pin_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_body_pin_03_63414': {
+        'hash': 63414,
+        'name': 'flashlight_body_pin_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_focusCylinder_63410': {
+        'hash': 63410,
+        'name': 'flashlight_focusCylinder',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_fuelDoor_axel_63402': {
+        'hash': 63402,
+        'name': 'flashlight_fuelDoor_axel',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_fuelDoor_body_63398': {
+        'hash': 63398,
+        'name': 'flashlight_fuelDoor_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_handle_body_63394': {
+        'hash': 63394,
+        'name': 'flashlight_handle_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_handle_pin_01_63390': {
+        'hash': 63390,
+        'name': 'flashlight_handle_pin_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_handle_pin_02_63426': {
+        'hash': 63426,
+        'name': 'flashlight_handle_pin_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'flashlight_handle_wraps_63406': {
+        'hash': 63406,
+        'name': 'flashlight_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Flint': {
+    'hash': 39484,
+    'name': 'Flint',
+    'embedded': {
+      'Flint_39368': {
+        'hash': 39368,
+        'name': 'Flint',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Primitive_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Primitive_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Flint_Training': {
+    'hash': 2356,
+    'name': 'Flint_Training',
+    'embedded': {
+      'Flint_Training_2350': {
+        'hash': 2350,
+        'name': 'Flint_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Float_Range_Operator': {
+    'hash': 50768,
+    'name': 'Float_Range_Operator',
+    'embedded': {
+      'Float_Range_Operator_13344': {
+        'hash': 13344,
+        'name': 'Float_Range_Operator',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicFloatRangeReceiver': {
+            'hash': 2700376822,
+            'name': 'LogicFloatRangeReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Flower_Blue': {
+    'hash': 23514,
+    'name': 'Flower_Blue',
+    'embedded': {
+      'Flower_Blue_28136': {
+        'hash': 28136,
+        'name': 'Flower_Blue',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Flower_Red': {
+    'hash': 61634,
+    'name': 'Flower_Red',
+    'embedded': {
+      'Flower_Red_27280': {
+        'hash': 27280,
+        'name': 'Flower_Red',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'FlyCam_Player': {
+    'hash': 44058,
+    'name': 'FlyCam_Player',
+    'embedded': {}
+  },
+  'Forage_Basket_Bag': {
+    'hash': 39880,
+    'name': 'Forage_Basket_Bag',
+    'embedded': {
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Dock_BL_42978': {
+        'hash': 42978,
+        'name': 'Dock_BL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BM_42976': {
+        'hash': 42976,
+        'name': 'Dock_BM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BR_42974': {
+        'hash': 42974,
+        'name': 'Dock_BR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_ML_42984': {
+        'hash': 42984,
+        'name': 'Dock_ML',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MM_42982': {
+        'hash': 42982,
+        'name': 'Dock_MM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MR_42980': {
+        'hash': 42980,
+        'name': 'Dock_MR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TL_42990': {
+        'hash': 42990,
+        'name': 'Dock_TL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TM_42988': {
+        'hash': 42988,
+        'name': 'Dock_TM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TR_42986': {
+        'hash': 42986,
+        'name': 'Dock_TR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Forage_Basket_Bag_43012': {
+        'hash': 43012,
+        'name': 'Forage_Basket_Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Bag_Attach_30776': {
+        'hash': 30776,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_55164': {
+        'hash': 55164,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'basket_bag_handle_wraps_56574': {
+        'hash': 56574,
+        'name': 'basket_bag_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_bottomStick_01_56570': {
+        'hash': 56570,
+        'name': 'basket_bottomStick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_bottomStick_02_56610': {
+        'hash': 56610,
+        'name': 'basket_bottomStick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_bottomStick_03_56558': {
+        'hash': 56558,
+        'name': 'basket_bottomStick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_bottomStick_04_56618': {
+        'hash': 56618,
+        'name': 'basket_bottomStick_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_bottomStick_05_56614': {
+        'hash': 56614,
+        'name': 'basket_bottomStick_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_handle_56602': {
+        'hash': 56602,
+        'name': 'basket_handle',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_outerPillar_01_56554': {
+        'hash': 56554,
+        'name': 'basket_outerPillar_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_outerPillar_02_56566': {
+        'hash': 56566,
+        'name': 'basket_outerPillar_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_outerPillar_03_56622': {
+        'hash': 56622,
+        'name': 'basket_outerPillar_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_outerPillar_04_56550': {
+        'hash': 56550,
+        'name': 'basket_outerPillar_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_outerPillar_05_56590': {
+        'hash': 56590,
+        'name': 'basket_outerPillar_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_rim_01_56598': {
+        'hash': 56598,
+        'name': 'basket_rim_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_rim_02_56578': {
+        'hash': 56578,
+        'name': 'basket_rim_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_rim_03_56562': {
+        'hash': 56562,
+        'name': 'basket_rim_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_thatch_body_56594': {
+        'hash': 56594,
+        'name': 'basket_thatch_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_topStick_01_56546': {
+        'hash': 56546,
+        'name': 'basket_topStick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_topStick_02_56606': {
+        'hash': 56606,
+        'name': 'basket_topStick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_topStick_03_56534': {
+        'hash': 56534,
+        'name': 'basket_topStick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_topStick_04_56586': {
+        'hash': 56586,
+        'name': 'basket_topStick_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_topStick_05_56538': {
+        'hash': 56538,
+        'name': 'basket_topStick_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_topStick_06_56582': {
+        'hash': 56582,
+        'name': 'basket_topStick_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_top_rim_56542': {
+        'hash': 56542,
+        'name': 'basket_top_rim',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Forage_Side_Pouch_Attachment': {
+    'hash': 32874,
+    'name': 'Forage_Side_Pouch_Attachment',
+    'embedded': {
+      'Dock_45700': {
+        'hash': 45700,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Forage_Side_Pouch_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Forage_Side_Pouch_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Insert_Bag_Attach_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Attach',
+        'savables': {}
+      },
+      'Storage_62414': {
+        'hash': 62414,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'forage_basket_attachment_cover_27470': {
+        'hash': 27470,
+        'name': 'forage_basket_attachment_cover',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'forage_basket_attachment_knot_01_27466': {
+        'hash': 27466,
+        'name': 'forage_basket_attachment_knot_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'forage_basket_attachment_stick_01_30790': {
+        'hash': 30790,
+        'name': 'forage_basket_attachment_stick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'forage_basket_attachment_stick_02_30786': {
+        'hash': 30786,
+        'name': 'forage_basket_attachment_stick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'forage_basket_rim_01_30798': {
+        'hash': 30798,
+        'name': 'forage_basket_rim_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'forage_basket_rim_02_30794': {
+        'hash': 30794,
+        'name': 'forage_basket_rim_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Forest_Chunk_Point_Generator': {
+    'hash': 45732,
+    'name': 'Forest_Chunk_Point_Generator',
+    'embedded': {
+      'Forest_Chunk_Point_Generator_16642': {
+        'hash': 16642,
+        'name': 'Forest_Chunk_Point_Generator',
+        'savables': {}
+      }
+    }
+  },
+  'Forest_Population': {
+    'hash': 18818,
+    'name': 'Forest_Population',
+    'embedded': {
+      'Forest_Population_16642': {
+        'hash': 16642,
+        'name': 'Forest_Population',
+        'savables': {
+          'BasicPopulationFolder': {
+            'hash': 1931537627,
+            'name': 'BasicPopulationFolder'
+          }
+        }
+      }
+    }
+  },
+  'Forge': {
+    'hash': 11872,
+    'name': 'Forge',
+    'embedded': {
+      'Fire_30100': {
+        'hash': 30100,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Forge_61848': {
+        'hash': 61848,
+        'name': 'Forge',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Forge_Area_43486': {
+        'hash': 43486,
+        'name': 'Forge_Area',
+        'savables': {}
+      }
+    }
+  },
+  'Forge_Training': {
+    'hash': 33628,
+    'name': 'Forge_Training',
+    'embedded': {
+      'Forge_Training_31154': {
+        'hash': 31154,
+        'name': 'Forge_Training',
+        'savables': {}
+      },
+      'Heat_Area_43486': {
+        'hash': 43486,
+        'name': 'Heat_Area',
+        'savables': {}
+      }
+    }
+  },
+  'Friend_Request_Token': {
+    'hash': 15314,
+    'name': 'Friend_Request_Token',
+    'embedded': {}
+  },
+  'Fruit_Tree_Path': {
+    'hash': 40982,
+    'name': 'Fruit_Tree_Path',
+    'embedded': {
+      'Fruit_Tree_Path_54338': {
+        'hash': 54338,
+        'name': 'Fruit_Tree_Path',
+        'savables': {
+          'PopulationPath': {
+            'hash': 7704646,
+            'name': 'PopulationPath'
+          }
+        }
+      }
+    }
+  },
+  'Gacha_Handle_': {
+    'hash': 34422,
+    'name': 'Gacha_Handle_',
+    'embedded': {
+      'Gacha_Handle__58484': {
+        'hash': 58484,
+        'name': 'Gacha_Handle_',
+        'savables': {}
+      },
+      'Handle_Pickup_13422': {
+        'hash': 13422,
+        'name': 'Handle_Pickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Full_Burnt': {
+    'hash': 52934,
+    'name': 'Garlic_Full_Burnt',
+    'embedded': {
+      'Cooking_64222': {
+        'hash': 64222,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Full_Burnt_52596': {
+        'hash': 52596,
+        'name': 'Garlic_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Full_Cooked': {
+    'hash': 52530,
+    'name': 'Garlic_Full_Cooked',
+    'embedded': {
+      'Cooking_63850': {
+        'hash': 63850,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Full_Cooked_52192': {
+        'hash': 52192,
+        'name': 'Garlic_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Full_Ripe': {
+    'hash': 52126,
+    'name': 'Garlic_Full_Ripe',
+    'embedded': {
+      'Cooking_61942': {
+        'hash': 61942,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Full_Ripe_49740': {
+        'hash': 49740,
+        'name': 'Garlic_Full_Ripe',
+        'savables': {
+          'BuildupPickup': {
+            'hash': 3373651539,
+            'name': 'BuildupPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Leaves_Parent_41624': {
+        'hash': 41624,
+        'name': 'Leaves_Parent',
+        'savables': {}
+      },
+      'Root_Parent_41626': {
+        'hash': 41626,
+        'name': 'Root_Parent',
+        'savables': {}
+      }
+    }
+  },
+  'Garlic_Full_Unripe': {
+    'hash': 49162,
+    'name': 'Garlic_Full_Unripe',
+    'embedded': {
+      'Cooking_61546': {
+        'hash': 61546,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Full_Unripe_48792': {
+        'hash': 48792,
+        'name': 'Garlic_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Half_Burnt': {
+    'hash': 60930,
+    'name': 'Garlic_Half_Burnt',
+    'embedded': {
+      'Cooking_36210': {
+        'hash': 36210,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Half_Burnt_60592': {
+        'hash': 60592,
+        'name': 'Garlic_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Half_Cooked': {
+    'hash': 60526,
+    'name': 'Garlic_Half_Cooked',
+    'embedded': {
+      'Cooking_35152': {
+        'hash': 35152,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Half_Cooked_60188': {
+        'hash': 60188,
+        'name': 'Garlic_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Half_Ripe': {
+    'hash': 60122,
+    'name': 'Garlic_Half_Ripe',
+    'embedded': {
+      'Cooking_34454': {
+        'hash': 34454,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Half_Ripe_59784': {
+        'hash': 59784,
+        'name': 'Garlic_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Half_Unripe': {
+    'hash': 59718,
+    'name': 'Garlic_Half_Unripe',
+    'embedded': {
+      'Cooking_34116': {
+        'hash': 34116,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Garlic_Half_Unripe_59380': {
+        'hash': 59380,
+        'name': 'Garlic_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Leaves': {
+    'hash': 1266,
+    'name': 'Garlic_Leaves',
+    'embedded': {
+      'Garlic_Leaves_57126': {
+        'hash': 57126,
+        'name': 'Garlic_Leaves',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'PullPickup_32134': {
+        'hash': 32134,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Garlic_Roots': {
+    'hash': 57564,
+    'name': 'Garlic_Roots',
+    'embedded': {
+      'Garlic_Roots_34536': {
+        'hash': 34536,
+        'name': 'Garlic_Roots',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'PullPickup_32134': {
+        'hash': 32134,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Geode_Tier_1': {
+    'hash': 59336,
+    'name': 'Geode_Tier_1',
+    'embedded': {
+      'Geode_Tier_1_56136': {
+        'hash': 56136,
+        'name': 'Geode_Tier_1',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Geode_Tier_1_Half_01': {
+    'hash': 29678,
+    'name': 'Geode_Tier_1_Half_01',
+    'embedded': {
+      'Geode_Tier_1_Half_01_26864': {
+        'hash': 26864,
+        'name': 'Geode_Tier_1_Half_01',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Geode_Tier_1_Half_02': {
+    'hash': 38512,
+    'name': 'Geode_Tier_1_Half_02',
+    'embedded': {
+      'Geode_Tier_1_Half_02_35456': {
+        'hash': 35456,
+        'name': 'Geode_Tier_1_Half_02',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Gift_Mail_Box': {
+    'hash': 56348,
+    'name': 'Gift_Mail_Box',
+    'embedded': {
+      'Gift_Mail_Box_17050': {
+        'hash': 17050,
+        'name': 'Gift_Mail_Box',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'SentGift': {
+            'hash': 661497638,
+            'name': 'SentGift'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Glowing_Mushroom_Recipe_Burnt_Stew': {
+    'hash': 47384,
+    'name': 'Glowing_Mushroom_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Glowing_Mushroom_Recipe_Cooked_Stew': {
+    'hash': 47362,
+    'name': 'Glowing_Mushroom_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Glowing_Mushroom_Recipe_Raw_Stew': {
+    'hash': 44774,
+    'name': 'Glowing_Mushroom_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'GoldCoin': {
+    'hash': 61648,
+    'name': 'GoldCoin',
+    'embedded': {
+      'GoldCoin_39174': {
+        'hash': 39174,
+        'name': 'GoldCoin',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_12524': {
+        'hash': 12524,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Gold_Boulder': {
+    'hash': 2584,
+    'name': 'Gold_Boulder',
+    'embedded': {
+      'Gold_Boulder_3932': {
+        'hash': 3932,
+        'name': 'Gold_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_7418': {
+        'hash': 7418,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Gold_Boulder_Parts': {
+    'hash': 47738,
+    'name': 'Gold_Boulder_Parts',
+    'embedded': {
+      'Gold_Boulder_Part_01_52930': {
+        'hash': 52930,
+        'name': 'Gold_Boulder_Part_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Gold_Boulder_Part_02_52926': {
+        'hash': 52926,
+        'name': 'Gold_Boulder_Part_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Gold_Boulder_Part_03_52922': {
+        'hash': 52922,
+        'name': 'Gold_Boulder_Part_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Gold_Boulder_Part_04_52934': {
+        'hash': 52934,
+        'name': 'Gold_Boulder_Part_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Gold_Boulder_Parts_52902': {
+        'hash': 52902,
+        'name': 'Gold_Boulder_Parts',
+        'savables': {}
+      }
+    }
+  },
+  'Gold_Ingot': {
+    'hash': 30092,
+    'name': 'Gold_Ingot',
+    'embedded': {
+      'Gold_Ingot_29980': {
+        'hash': 29980,
+        'name': 'Gold_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_13048': {
+        'hash': 13048,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Gold_Ore': {
+    'hash': 61650,
+    'name': 'Gold_Ore',
+    'embedded': {
+      'Gold_Ore_39896': {
+        'hash': 39896,
+        'name': 'Gold_Ore',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Gotera': {
+    'hash': 9466,
+    'name': 'Gotera',
+    'embedded': {
+      'Dart_Shooter_56642': {
+        'hash': 56642,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Gotera_7278': {
+        'hash': 7278,
+        'name': 'Gotera',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Gotera_AI_22350': {
+        'hash': 22350,
+        'name': 'Gotera_AI',
+        'savables': {}
+      },
+      'Gotera_Body_10036': {
+        'hash': 10036,
+        'name': 'Gotera_Body',
+        'savables': {}
+      },
+      'Impactor_63610': {
+        'hash': 63610,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Physical_Torso_8164': {
+        'hash': 8164,
+        'name': 'Physical_Torso',
+        'savables': {}
+      },
+      'Seed_Spray_1172': {
+        'hash': 1172,
+        'name': 'Seed_Spray',
+        'savables': {}
+      },
+      'Spawn_Drop_16220': {
+        'hash': 16220,
+        'name': 'Spawn_Drop',
+        'savables': {}
+      },
+      'root_jnt_17218': {
+        'hash': 17218,
+        'name': 'root_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Ash_Bomb': {
+    'hash': 56764,
+    'name': 'Gotera_Ash_Bomb',
+    'embedded': {
+      'AI_16472': {
+        'hash': 16472,
+        'name': 'AI',
+        'savables': {}
+      },
+      'Explosion_7834': {
+        'hash': 7834,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Gotera_Ash_Bomb_40780': {
+        'hash': 40780,
+        'name': 'Gotera_Ash_Bomb',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Gotera_Ash_Variant': {
+    'hash': 61448,
+    'name': 'Gotera_Ash_Variant',
+    'embedded': {
+      'Dart_Shooter_6022': {
+        'hash': 6022,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Gotera_AI_22350': {
+        'hash': 22350,
+        'name': 'Gotera_AI',
+        'savables': {}
+      },
+      'Gotera_Ash_Variant_7278': {
+        'hash': 7278,
+        'name': 'Gotera_Ash_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Gotera_Body_10036': {
+        'hash': 10036,
+        'name': 'Gotera_Body',
+        'savables': {}
+      },
+      'Impactor_63610': {
+        'hash': 63610,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Physical_Torso_8164': {
+        'hash': 8164,
+        'name': 'Physical_Torso',
+        'savables': {}
+      },
+      'Seed_Spray_1172': {
+        'hash': 1172,
+        'name': 'Seed_Spray',
+        'savables': {}
+      },
+      'Spawn_Drop_16220': {
+        'hash': 16220,
+        'name': 'Spawn_Drop',
+        'savables': {}
+      },
+      'root_jnt_17218': {
+        'hash': 17218,
+        'name': 'root_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Big_Dart': {
+    'hash': 26780,
+    'name': 'Gotera_Big_Dart',
+    'embedded': {
+      'Dart_62940': {
+        'hash': 62940,
+        'name': 'Dart',
+        'savables': {}
+      },
+      'Gotera_Big_Dart_3092': {
+        'hash': 3092,
+        'name': 'Gotera_Big_Dart',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Gotera_Big_Seed_Spray': {
+    'hash': 18468,
+    'name': 'Gotera_Big_Seed_Spray',
+    'embedded': {
+      'Gotera_Big_Seed_Spray_44772': {
+        'hash': 44772,
+        'name': 'Gotera_Big_Seed_Spray',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Birch_Variant': {
+    'hash': 2370,
+    'name': 'Gotera_Birch_Variant',
+    'embedded': {
+      'Dart_Shooter_6022': {
+        'hash': 6022,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Gotera_AI_22350': {
+        'hash': 22350,
+        'name': 'Gotera_AI',
+        'savables': {}
+      },
+      'Gotera_Birch_Variant_7278': {
+        'hash': 7278,
+        'name': 'Gotera_Birch_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Gotera_Body_10036': {
+        'hash': 10036,
+        'name': 'Gotera_Body',
+        'savables': {}
+      },
+      'Impactor_63610': {
+        'hash': 63610,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Physical_Torso_8164': {
+        'hash': 8164,
+        'name': 'Physical_Torso',
+        'savables': {}
+      },
+      'Seed_Spray_1172': {
+        'hash': 1172,
+        'name': 'Seed_Spray',
+        'savables': {}
+      },
+      'Spawn_Drop_16220': {
+        'hash': 16220,
+        'name': 'Spawn_Drop',
+        'savables': {}
+      },
+      'root_jnt_17218': {
+        'hash': 17218,
+        'name': 'root_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Dart': {
+    'hash': 3088,
+    'name': 'Gotera_Dart',
+    'embedded': {
+      'Dart_62940': {
+        'hash': 62940,
+        'name': 'Dart',
+        'savables': {}
+      },
+      'Gotera_Dart_3092': {
+        'hash': 3092,
+        'name': 'Gotera_Dart',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Gotera_Redwood_Variant': {
+    'hash': 27128,
+    'name': 'Gotera_Redwood_Variant',
+    'embedded': {
+      'Dart_Shooter_56642': {
+        'hash': 56642,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Gotera_AI_22350': {
+        'hash': 22350,
+        'name': 'Gotera_AI',
+        'savables': {}
+      },
+      'Gotera_Body_10036': {
+        'hash': 10036,
+        'name': 'Gotera_Body',
+        'savables': {}
+      },
+      'Gotera_Redwood_Variant_7278': {
+        'hash': 7278,
+        'name': 'Gotera_Redwood_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Impactor_19042': {
+        'hash': 19042,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Impactor_19160': {
+        'hash': 19160,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Impactor_63610': {
+        'hash': 63610,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Physical_Torso_8164': {
+        'hash': 8164,
+        'name': 'Physical_Torso',
+        'savables': {}
+      },
+      'Seed_Spray_1172': {
+        'hash': 1172,
+        'name': 'Seed_Spray',
+        'savables': {}
+      },
+      'Spawn_Drop_16220': {
+        'hash': 16220,
+        'name': 'Spawn_Drop',
+        'savables': {}
+      },
+      'root_jnt_17218': {
+        'hash': 17218,
+        'name': 'root_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Seed_Spray': {
+    'hash': 31540,
+    'name': 'Gotera_Seed_Spray',
+    'embedded': {
+      'Gotera_Seed_Spray_44772': {
+        'hash': 44772,
+        'name': 'Gotera_Seed_Spray',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Seedling_Orb': {
+    'hash': 59342,
+    'name': 'Gotera_Seedling_Orb',
+    'embedded': {
+      'Gotera_Seedling_Orb_59268': {
+        'hash': 59268,
+        'name': 'Gotera_Seedling_Orb',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Stun_Explosion_58370': {
+        'hash': 58370,
+        'name': 'Stun_Explosion',
+        'savables': {}
+      }
+    }
+  },
+  'Gotera_Walnut_Bomb': {
+    'hash': 35174,
+    'name': 'Gotera_Walnut_Bomb',
+    'embedded': {
+      'Explosion_7834': {
+        'hash': 7834,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Gotera_Walnut_Bomb_40780': {
+        'hash': 40780,
+        'name': 'Gotera_Walnut_Bomb',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Gotera_Walnut_Variant': {
+    'hash': 38096,
+    'name': 'Gotera_Walnut_Variant',
+    'embedded': {
+      'Big_Dart_Shooter_(1)_4010': {
+        'hash': 4010,
+        'name': 'Big_Dart_Shooter_(1)',
+        'savables': {}
+      },
+      'Big_Dart_Shooter_(2)_4572': {
+        'hash': 4572,
+        'name': 'Big_Dart_Shooter_(2)',
+        'savables': {}
+      },
+      'Big_Dart_Shooter_5974': {
+        'hash': 5974,
+        'name': 'Big_Dart_Shooter',
+        'savables': {}
+      },
+      'Dart_Shooter_(1)_37542': {
+        'hash': 37542,
+        'name': 'Dart_Shooter_(1)',
+        'savables': {}
+      },
+      'Dart_Shooter_56642': {
+        'hash': 56642,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Dart_Shooter_5986': {
+        'hash': 5986,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Dart_Shooter_5998': {
+        'hash': 5998,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Dart_Shooter_6010': {
+        'hash': 6010,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Dart_Shooter_6022': {
+        'hash': 6022,
+        'name': 'Dart_Shooter',
+        'savables': {}
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Gotera_AI_22350': {
+        'hash': 22350,
+        'name': 'Gotera_AI',
+        'savables': {}
+      },
+      'Gotera_Body_10036': {
+        'hash': 10036,
+        'name': 'Gotera_Body',
+        'savables': {}
+      },
+      'Gotera_Walnut_Variant_7278': {
+        'hash': 7278,
+        'name': 'Gotera_Walnut_Variant',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Impactor_63610': {
+        'hash': 63610,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Physical_Torso_8164': {
+        'hash': 8164,
+        'name': 'Physical_Torso',
+        'savables': {}
+      },
+      'Seed_Spray_1172': {
+        'hash': 1172,
+        'name': 'Seed_Spray',
+        'savables': {}
+      },
+      'Spawn_Drop_16220': {
+        'hash': 16220,
+        'name': 'Spawn_Drop',
+        'savables': {}
+      },
+      'root_jnt_17218': {
+        'hash': 17218,
+        'name': 'root_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Gourd_Canteen': {
+    'hash': 29032,
+    'name': 'Gourd_Canteen',
+    'embedded': {
+      'Gourd_Canteen_26784': {
+        'hash': 26784,
+        'name': 'Gourd_Canteen',
+        'savables': {
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Lid_Pickup_27480': {
+        'hash': 27480,
+        'name': 'Lid_Pickup',
+        'savables': {
+          'CapPickup': {
+            'hash': 3082855726,
+            'name': 'CapPickup'
+          }
+        }
+      }
+    }
+  },
+  'Grass_Clump': {
+    'hash': 57872,
+    'name': 'Grass_Clump',
+    'embedded': {
+      'Fire_30100': {
+        'hash': 30100,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Grass_Clump_12138': {
+        'hash': 12138,
+        'name': 'Grass_Clump',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      },
+      'Insert_Grass_7796': {
+        'hash': 7796,
+        'name': 'Insert_Grass',
+        'savables': {}
+      }
+    }
+  },
+  'Gravestone_Parts': {
+    'hash': 2596,
+    'name': 'Gravestone_Parts',
+    'embedded': {
+      'Gravestone_Parts_37752': {
+        'hash': 37752,
+        'name': 'Gravestone_Parts',
+        'savables': {}
+      },
+      'gravestone_base_LOD0_1602': {
+        'hash': 1602,
+        'name': 'gravestone_base_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type1_LOD0_1578': {
+        'hash': 1578,
+        'name': 'gravestone_brick_type1_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type1_LOD0_1596': {
+        'hash': 1596,
+        'name': 'gravestone_brick_type1_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type1_LOD0_1604': {
+        'hash': 1604,
+        'name': 'gravestone_brick_type1_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type1_LOD0_1608': {
+        'hash': 1608,
+        'name': 'gravestone_brick_type1_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type2_LOD0_1590': {
+        'hash': 1590,
+        'name': 'gravestone_brick_type2_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type2_LOD0_1606': {
+        'hash': 1606,
+        'name': 'gravestone_brick_type2_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type2_LOD0_1610': {
+        'hash': 1610,
+        'name': 'gravestone_brick_type2_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type2_LOD0_1614': {
+        'hash': 1614,
+        'name': 'gravestone_brick_type2_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type3_LOD0_1572': {
+        'hash': 1572,
+        'name': 'gravestone_brick_type3_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type3_LOD0_1594': {
+        'hash': 1594,
+        'name': 'gravestone_brick_type3_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type3_LOD0_1600': {
+        'hash': 1600,
+        'name': 'gravestone_brick_type3_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type3_LOD0_1612': {
+        'hash': 1612,
+        'name': 'gravestone_brick_type3_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type4_LOD0_1576': {
+        'hash': 1576,
+        'name': 'gravestone_brick_type4_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type4_LOD0_1582': {
+        'hash': 1582,
+        'name': 'gravestone_brick_type4_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_brick_type4_LOD0_1586': {
+        'hash': 1586,
+        'name': 'gravestone_brick_type4_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_spike_large_LOD0_1580': {
+        'hash': 1580,
+        'name': 'gravestone_spike_large_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_spike_large_LOD0_1588': {
+        'hash': 1588,
+        'name': 'gravestone_spike_large_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_spike_large_LOD0_1598': {
+        'hash': 1598,
+        'name': 'gravestone_spike_large_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_spike_small_LOD0_1584': {
+        'hash': 1584,
+        'name': 'gravestone_spike_small_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_spike_small_LOD0_1592': {
+        'hash': 1592,
+        'name': 'gravestone_spike_small_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'gravestone_torus_LOD0_1574': {
+        'hash': 1574,
+        'name': 'gravestone_torus_LOD0',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Great_Sword_Blade': {
+    'hash': 63886,
+    'name': 'Great_Sword_Blade',
+    'embedded': {
+      'Great_Sword_Blade_84': {
+        'hash': 84,
+        'name': 'Great_Sword_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_62004': {
+        'hash': 62004,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Large_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Large_SwordType',
+        'savables': {}
+      },
+      'metal_blade_greatsword_full_geo_LOD0_60392': {
+        'hash': 60392,
+        'name': 'metal_blade_greatsword_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Greater_Gotera_Charge_Explosion': {
+    'hash': 5316,
+    'name': 'Greater_Gotera_Charge_Explosion',
+    'embedded': {
+      'Greater_Gotera_Charge_Explosion_58370': {
+        'hash': 58370,
+        'name': 'Greater_Gotera_Charge_Explosion',
+        'savables': {}
+      }
+    }
+  },
+  'Greater_Gotera_Seed_Spray': {
+    'hash': 13476,
+    'name': 'Greater_Gotera_Seed_Spray',
+    'embedded': {
+      'Greater_Gotera_Seed_Spray_44772': {
+        'hash': 44772,
+        'name': 'Greater_Gotera_Seed_Spray',
+        'savables': {}
+      }
+    }
+  },
+  'Green_Crystal_cluster_03': {
+    'hash': 23836,
+    'name': 'Green_Crystal_cluster_03',
+    'embedded': {
+      'Green_Crystal_cluster_03_54542': {
+        'hash': 54542,
+        'name': 'Green_Crystal_cluster_03',
+        'savables': {}
+      }
+    }
+  },
+  'Guard': {
+    'hash': 51672,
+    'name': 'Guard',
+    'embedded': {
+      'Guard_51546': {
+        'hash': 51546,
+        'name': 'Guard',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_56294': {
+        'hash': 56294,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_SwordType_39370': {
+        'hash': 39370,
+        'name': 'Slot_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Guard_Fancy': {
+    'hash': 62140,
+    'name': 'Guard_Fancy',
+    'embedded': {
+      'Guard_Fancy_51546': {
+        'hash': 51546,
+        'name': 'Guard_Fancy',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_56592': {
+        'hash': 56592,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_Deco_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Deco',
+        'savables': {}
+      },
+      'Slot_SwordType_39370': {
+        'hash': 39370,
+        'name': 'Slot_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Guard_Handle': {
+    'hash': 43186,
+    'name': 'Guard_Handle',
+    'embedded': {
+      'Guard_Handle_51546': {
+        'hash': 51546,
+        'name': 'Guard_Handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Mid_39368': {
+        'hash': 39368,
+        'name': 'Insert_Mid',
+        'savables': {}
+      },
+      'Slot_End_39370': {
+        'hash': 39370,
+        'name': 'Slot_End',
+        'savables': {}
+      }
+    }
+  },
+  'Guard_Hemisphere': {
+    'hash': 34428,
+    'name': 'Guard_Hemisphere',
+    'embedded': {
+      'Guard_Hemisphere_51546': {
+        'hash': 51546,
+        'name': 'Guard_Hemisphere',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_56886': {
+        'hash': 56886,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_Deco_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Deco',
+        'savables': {}
+      },
+      'Slot_SwordType_39370': {
+        'hash': 39370,
+        'name': 'Slot_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Guard_Pointy_Ends': {
+    'hash': 28160,
+    'name': 'Guard_Pointy_Ends',
+    'embedded': {
+      'Guard_Pointy_Ends_51546': {
+        'hash': 51546,
+        'name': 'Guard_Pointy_Ends',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_57188': {
+        'hash': 57188,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_31108': {
+        'hash': 31108,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Guard_Round_Ends': {
+    'hash': 21776,
+    'name': 'Guard_Round_Ends',
+    'embedded': {
+      'Guard_Round_Ends_51546': {
+        'hash': 51546,
+        'name': 'Guard_Round_Ends',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Mid_39368': {
+        'hash': 39368,
+        'name': 'Insert_Mid',
+        'savables': {}
+      },
+      'Slot_End_39370': {
+        'hash': 39370,
+        'name': 'Slot_End',
+        'savables': {}
+      }
+    }
+  },
+  'Guard_Straight_Ends': {
+    'hash': 17348,
+    'name': 'Guard_Straight_Ends',
+    'embedded': {
+      'Guard_Straight_Ends_51546': {
+        'hash': 51546,
+        'name': 'Guard_Straight_Ends',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_57430': {
+        'hash': 57430,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_30024': {
+        'hash': 30024,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Gymnasium_Prefab_Spawner': {
+    'hash': 25312,
+    'name': 'Gymnasium_Prefab_Spawner',
+    'embedded': {
+      'Gymnasium_Prefab_Spawner_25334': {
+        'hash': 25334,
+        'name': 'Gymnasium_Prefab_Spawner',
+        'savables': {
+          'GymnasiumOnDemandPrefabSpawner': {
+            'hash': 701033518,
+            'name': 'GymnasiumOnDemandPrefabSpawner'
+          }
+        }
+      },
+      'Spawn_Area_4162': {
+        'hash': 4162,
+        'name': 'Spawn_Area',
+        'savables': {
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Gymnasium_Teleport_Tablet': {
+    'hash': 2718,
+    'name': 'Gymnasium_Teleport_Tablet',
+    'embedded': {
+      'Collision_27112': {
+        'hash': 27112,
+        'name': 'Collision',
+        'savables': {}
+      },
+      'Gymnasium_Teleport_Tablet_2062': {
+        'hash': 2062,
+        'name': 'Gymnasium_Teleport_Tablet',
+        'savables': {}
+      }
+    }
+  },
+  'Gymnasium_Xp_Display_View': {
+    'hash': 57304,
+    'name': 'Gymnasium_Xp_Display_View',
+    'embedded': {
+      'Back_Button_17050': {
+        'hash': 17050,
+        'name': 'Back_Button',
+        'savables': {}
+      },
+      'Forward_Button_17050': {
+        'hash': 17050,
+        'name': 'Forward_Button',
+        'savables': {}
+      },
+      'Gymnasium_Xp_Display_View_57232': {
+        'hash': 57232,
+        'name': 'Gymnasium_Xp_Display_View',
+        'savables': {}
+      },
+      'Increase_Button_17050': {
+        'hash': 17050,
+        'name': 'Increase_Button',
+        'savables': {}
+      },
+      'Increase_Max_Button_17050': {
+        'hash': 17050,
+        'name': 'Increase_Max_Button',
+        'savables': {}
+      },
+      'Reset_Button_17050': {
+        'hash': 17050,
+        'name': 'Reset_Button',
+        'savables': {}
+      }
+    }
+  },
+  'Hammer': {
+    'hash': 61660,
+    'name': 'Hammer',
+    'embedded': {}
+  },
+  'Hammer_Head': {
+    'hash': 43146,
+    'name': 'Hammer_Head',
+    'embedded': {
+      'Hammer_Head_42978': {
+        'hash': 42978,
+        'name': 'Hammer_Head',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_10366': {
+        'hash': 10366,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_52192': {
+        'hash': 52192,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      }
+    }
+  },
+  'Hammer_Head_Small': {
+    'hash': 15476,
+    'name': 'Hammer_Head_Small',
+    'embedded': {
+      'Hammer_Head_Small_18788': {
+        'hash': 18788,
+        'name': 'Hammer_Head_Small',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_10670': {
+        'hash': 10670,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_18784': {
+        'hash': 18784,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      }
+    }
+  },
+  'Hammer_Training': {
+    'hash': 47018,
+    'name': 'Hammer_Training',
+    'embedded': {
+      'Hammer_Training_44084': {
+        'hash': 44084,
+        'name': 'Hammer_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hand_Camera': {
+    'hash': 59806,
+    'name': 'Hand_Camera',
+    'embedded': {}
+  },
+  'Handle_Bow': {
+    'hash': 64410,
+    'name': 'Handle_Bow',
+    'embedded': {
+      'Handle_Bow_1188': {
+        'hash': 1188,
+        'name': 'Handle_Bow',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Grass_11474': {
+        'hash': 11474,
+        'name': 'Slot_Grass',
+        'savables': {}
+      },
+      'Slot_Grass_29036': {
+        'hash': 29036,
+        'name': 'Slot_Grass',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Fist': {
+    'hash': 22988,
+    'name': 'Handle_Fist',
+    'embedded': {
+      'Handle_Fist_45004': {
+        'hash': 45004,
+        'name': 'Handle_Fist',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_7356': {
+        'hash': 7356,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_Deco_22982': {
+        'hash': 22982,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_22992': {
+        'hash': 22992,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_23002': {
+        'hash': 23002,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_54114': {
+        'hash': 54114,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Multi_22990': {
+        'hash': 22990,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Large_Branch': {
+    'hash': 61098,
+    'name': 'Handle_Large_Branch',
+    'embedded': {
+      'Handle_Large_Branch_61094': {
+        'hash': 61094,
+        'name': 'Handle_Large_Branch',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Multi_20330': {
+        'hash': 20330,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Primitive_AxeType_55026': {
+        'hash': 55026,
+        'name': 'Slot_Primitive_AxeType',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Large_Cool': {
+    'hash': 25290,
+    'name': 'Handle_Large_Cool',
+    'embedded': {
+      'Handle_Large_Cool_25294': {
+        'hash': 25294,
+        'name': 'Handle_Large_Cool',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_37768': {
+        'hash': 37768,
+        'name': 'Heat_Point',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_43172': {
+        'hash': 43172,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_64610': {
+        'hash': 64610,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_29320': {
+        'hash': 29320,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_43166': {
+        'hash': 43166,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Large_Standard': {
+    'hash': 43252,
+    'name': 'Handle_Large_Standard',
+    'embedded': {}
+  },
+  'Handle_Long_Straight': {
+    'hash': 20300,
+    'name': 'Handle_Long_Straight',
+    'embedded': {
+      'Dock_32818': {
+        'hash': 32818,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Long_Straight_25294': {
+        'hash': 25294,
+        'name': 'Handle_Long_Straight',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_53492': {
+        'hash': 53492,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_53692': {
+        'hash': 53692,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_(1)_63178': {
+        'hash': 63178,
+        'name': 'Slot_Multi_(1)',
+        'savables': {}
+      },
+      'Slot_Multi_53060': {
+        'hash': 53060,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_53074': {
+        'hash': 53074,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_63218': {
+        'hash': 63218,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63270': {
+        'hash': 63270,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63318': {
+        'hash': 63318,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Medium_Branch': {
+    'hash': 61400,
+    'name': 'Handle_Medium_Branch',
+    'embedded': {
+      'Handle_Medium_Branch_61404': {
+        'hash': 61404,
+        'name': 'Handle_Medium_Branch',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_45470': {
+        'hash': 45470,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_15462': {
+        'hash': 15462,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_29458': {
+        'hash': 29458,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_52880': {
+        'hash': 52880,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_PommelType_55836': {
+        'hash': 55836,
+        'name': 'Slot_PommelType',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Medium_Cool': {
+    'hash': 61856,
+    'name': 'Handle_Medium_Cool',
+    'embedded': {
+      'Handle_Medium_Cool_61852': {
+        'hash': 61852,
+        'name': 'Handle_Medium_Cool',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_8548': {
+        'hash': 8548,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_57058': {
+        'hash': 57058,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_59436': {
+        'hash': 59436,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_3558': {
+        'hash': 3558,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_59224': {
+        'hash': 59224,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Medium_Curved': {
+    'hash': 19316,
+    'name': 'Handle_Medium_Curved',
+    'embedded': {
+      'Handle_Medium_Curved_19318': {
+        'hash': 19318,
+        'name': 'Handle_Medium_Curved',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_9036': {
+        'hash': 9036,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_51182': {
+        'hash': 51182,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_7860': {
+        'hash': 7860,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Medium_Ridged': {
+    'hash': 60598,
+    'name': 'Handle_Medium_Ridged',
+    'embedded': {
+      'Handle_Medium_Ridged_44084': {
+        'hash': 44084,
+        'name': 'Handle_Medium_Ridged',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Pole_19996': {
+        'hash': 19996,
+        'name': 'Slot_Pole',
+        'savables': {}
+      },
+      'Slot_Pole_64914': {
+        'hash': 64914,
+        'name': 'Slot_Pole',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Medium_Standard': {
+    'hash': 41438,
+    'name': 'Handle_Medium_Standard',
+    'embedded': {
+      'Handle_Medium_Standard_44084': {
+        'hash': 44084,
+        'name': 'Handle_Medium_Standard',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Pole_20070': {
+        'hash': 20070,
+        'name': 'Slot_Pole',
+        'savables': {}
+      },
+      'Slot_Pole_64914': {
+        'hash': 64914,
+        'name': 'Slot_Pole',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Medium_Straight': {
+    'hash': 19180,
+    'name': 'Handle_Medium_Straight',
+    'embedded': {
+      'Dock_39120': {
+        'hash': 39120,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Medium_Straight_19154': {
+        'hash': 19154,
+        'name': 'Handle_Medium_Straight',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_53492': {
+        'hash': 53492,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_53692': {
+        'hash': 53692,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_(1)_63178': {
+        'hash': 63178,
+        'name': 'Slot_Multi_(1)',
+        'savables': {}
+      },
+      'Slot_Multi_53060': {
+        'hash': 53060,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_53074': {
+        'hash': 53074,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_63218': {
+        'hash': 63218,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63270': {
+        'hash': 63270,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63318': {
+        'hash': 63318,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Round_Fist': {
+    'hash': 3506,
+    'name': 'Handle_Round_Fist',
+    'embedded': {
+      'Handle_Round_Fist_3514': {
+        'hash': 3514,
+        'name': 'Handle_Round_Fist',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Deco_31482': {
+        'hash': 31482,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_38156': {
+        'hash': 38156,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_50738': {
+        'hash': 50738,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_57746': {
+        'hash': 57746,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Multi_54114': {
+        'hash': 54114,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Short': {
+    'hash': 42230,
+    'name': 'Handle_Short',
+    'embedded': {
+      'Handle_Short_42104': {
+        'hash': 42104,
+        'name': 'Handle_Short',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Large_SwordType_Craft_54356': {
+        'hash': 54356,
+        'name': 'Slot_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Large_SwordType_Craft_6134': {
+        'hash': 6134,
+        'name': 'Slot_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_6136': {
+        'hash': 6136,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_6138': {
+        'hash': 6138,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_PommelType_20654': {
+        'hash': 20654,
+        'name': 'Slot_PommelType',
+        'savables': {}
+      },
+      'Slot_PommelType_30776': {
+        'hash': 30776,
+        'name': 'Slot_PommelType',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Short_C_Curve': {
+    'hash': 34898,
+    'name': 'Handle_Short_C_Curve',
+    'embedded': {
+      'Handle_Short_C_Curve_44084': {
+        'hash': 44084,
+        'name': 'Handle_Short_C_Curve',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_9524': {
+        'hash': 9524,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_Large_SwordType_Craft_5628': {
+        'hash': 5628,
+        'name': 'Slot_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Large_SwordType_Craft_5714': {
+        'hash': 5714,
+        'name': 'Slot_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_5624': {
+        'hash': 5624,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_5626': {
+        'hash': 5626,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_PommelType_5686': {
+        'hash': 5686,
+        'name': 'Slot_PommelType',
+        'savables': {}
+      },
+      'Slot_PommelType_5700': {
+        'hash': 5700,
+        'name': 'Slot_PommelType',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Short_Cool': {
+    'hash': 5920,
+    'name': 'Handle_Short_Cool',
+    'embedded': {
+      'Handle_Short_Cool_5922': {
+        'hash': 5922,
+        'name': 'Handle_Short_Cool',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_51674': {
+        'hash': 51674,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_43890': {
+        'hash': 43890,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Large_SwordType_Craft_33946': {
+        'hash': 33946,
+        'name': 'Slot_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_48480': {
+        'hash': 48480,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Short_Pointy_End': {
+    'hash': 28636,
+    'name': 'Handle_Short_Pointy_End',
+    'embedded': {
+      'Handle_Short_Pointy_End_44084': {
+        'hash': 44084,
+        'name': 'Handle_Short_Pointy_End',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Heat_Point_Collection_10000': {
+        'hash': 10000,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_14502': {
+        'hash': 14502,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Large_SwordType_Craft_9736': {
+        'hash': 9736,
+        'name': 'Slot_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_18472': {
+        'hash': 18472,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Short_S_Curve': {
+    'hash': 27820,
+    'name': 'Handle_Short_S_Curve',
+    'embedded': {
+      'Handle_Short_S_Curve_44084': {
+        'hash': 44084,
+        'name': 'Handle_Short_S_Curve',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Mid_20238': {
+        'hash': 20238,
+        'name': 'Slot_Mid',
+        'savables': {}
+      },
+      'Slot_Mid_64914': {
+        'hash': 64914,
+        'name': 'Slot_Mid',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Short_Taper': {
+    'hash': 24198,
+    'name': 'Handle_Short_Taper',
+    'embedded': {
+      'Handle_Short_Taper_24200': {
+        'hash': 24200,
+        'name': 'Handle_Short_Taper',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Mid_20296': {
+        'hash': 20296,
+        'name': 'Slot_Mid',
+        'savables': {}
+      },
+      'Slot_Mid_64914': {
+        'hash': 64914,
+        'name': 'Slot_Mid',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Spear': {
+    'hash': 20640,
+    'name': 'Handle_Spear',
+    'embedded': {
+      'Handle_Spear_24200': {
+        'hash': 24200,
+        'name': 'Handle_Spear',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Deco_4866': {
+        'hash': 4866,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Pole_64914': {
+        'hash': 64914,
+        'name': 'Slot_Pole',
+        'savables': {}
+      }
+    }
+  },
+  'Handle_Tonfa': {
+    'hash': 57838,
+    'name': 'Handle_Tonfa',
+    'embedded': {
+      'Handle_Tonfa_57844': {
+        'hash': 57844,
+        'name': 'Handle_Tonfa',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_52822': {
+        'hash': 52822,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_HammerType_End_Cap_47874': {
+        'hash': 47874,
+        'name': 'Slot_HammerType_End_Cap',
+        'savables': {}
+      },
+      'Slot_Multi_64782': {
+        'hash': 64782,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Shield_37414': {
+        'hash': 37414,
+        'name': 'Slot_Shield',
+        'savables': {}
+      }
+    }
+  },
+  'Handy_Cam': {
+    'hash': 13790,
+    'name': 'Handy_Cam',
+    'embedded': {}
+  },
+  'Hanging_Health_Vine_01': {
+    'hash': 52952,
+    'name': 'Hanging_Health_Vine_01',
+    'embedded': {
+      'Directional_Encounter_43896': {
+        'hash': 43896,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Hanging_Health_Vine_01_6398': {
+        'hash': 6398,
+        'name': 'Hanging_Health_Vine_01',
+        'savables': {}
+      }
+    }
+  },
+  'Hanging_Health_Vine_02': {
+    'hash': 56796,
+    'name': 'Hanging_Health_Vine_02',
+    'embedded': {
+      'Directional_Encounter_43896': {
+        'hash': 43896,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Hanging_Health_Vine_02_6398': {
+        'hash': 6398,
+        'name': 'Hanging_Health_Vine_02',
+        'savables': {}
+      }
+    }
+  },
+  'Hanging_Health_Vine_03': {
+    'hash': 53496,
+    'name': 'Hanging_Health_Vine_03',
+    'embedded': {
+      'Directional_Encounter_43896': {
+        'hash': 43896,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Hanging_Health_Vine_03_6398': {
+        'hash': 6398,
+        'name': 'Hanging_Health_Vine_03',
+        'savables': {}
+      }
+    }
+  },
+  'Hanging_Loot_Box_Platform': {
+    'hash': 54462,
+    'name': 'Hanging_Loot_Box_Platform',
+    'embedded': {
+      'Hanging_Loot_Box_Platform_12670': {
+        'hash': 12670,
+        'name': 'Hanging_Loot_Box_Platform',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Boxes_(1)_18788': {
+        'hash': 18788,
+        'name': 'Spawn_Boxes_(1)',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Spawn_Boxes_(2)_18856': {
+        'hash': 18856,
+        'name': 'Spawn_Boxes_(2)',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Spawn_Boxes_(3)_18766': {
+        'hash': 18766,
+        'name': 'Spawn_Boxes_(3)',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Spawn_Boxes_53424': {
+        'hash': 53424,
+        'name': 'Spawn_Boxes',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Hanging_Loot_Sack': {
+    'hash': 49658,
+    'name': 'Hanging_Loot_Sack',
+    'embedded': {
+      'Box_5934': {
+        'hash': 5934,
+        'name': 'Box',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Hanging_Loot_Sack_12670': {
+        'hash': 12670,
+        'name': 'Hanging_Loot_Sack',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Link_5938': {
+        'hash': 5938,
+        'name': 'Link',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Hard_Metal_Small_Bits': {
+    'hash': 62594,
+    'name': 'Hard_Metal_Small_Bits',
+    'embedded': {
+      'Hard_Metal_Small_Bits_62578': {
+        'hash': 62578,
+        'name': 'Hard_Metal_Small_Bits',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Hard_Plate_Metal_Medium_Square': {
+    'hash': 50988,
+    'name': 'Hard_Plate_Metal_Medium_Square',
+    'embedded': {
+      'Hard_Plate_Metal_Medium_Square_51004': {
+        'hash': 51004,
+        'name': 'Hard_Plate_Metal_Medium_Square',
+        'savables': {
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Mesh_51176': {
+        'hash': 51176,
+        'name': 'Mesh',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'hardPlate_metal_medium_square_LOD0_52344': {
+        'hash': 52344,
+        'name': 'hardPlate_metal_medium_square_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Healing_Pod': {
+    'hash': 44360,
+    'name': 'Healing_Pod',
+    'embedded': {
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Healing_Pod_15532': {
+        'hash': 15532,
+        'name': 'Healing_Pod',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Healing_Pod_Plant': {
+    'hash': 48826,
+    'name': 'Healing_Pod_Plant',
+    'embedded': {
+      'Healing_Pod_Plant_64192': {
+        'hash': 64192,
+        'name': 'Healing_Pod_Plant',
+        'savables': {}
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Spawn_Buried_57238': {
+        'hash': 57238,
+        'name': 'Spawn_Buried',
+        'savables': {
+          'SpawnBuried': {
+            'hash': 654225716,
+            'name': 'SpawnBuried'
+          }
+        }
+      }
+    }
+  },
+  'Heart_Receptacle': {
+    'hash': 56090,
+    'name': 'Heart_Receptacle',
+    'embedded': {
+      'Fake_Interactable_64848': {
+        'hash': 64848,
+        'name': 'Fake_Interactable',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Heart_Receptacle_37620': {
+        'hash': 37620,
+        'name': 'Heart_Receptacle',
+        'savables': {}
+      }
+    }
+  },
+  'Hebios_Buried_Spawn_Area': {
+    'hash': 51290,
+    'name': 'Hebios_Buried_Spawn_Area',
+    'embedded': {
+      'Hebios_Buried_Spawn_Area_51274': {
+        'hash': 51274,
+        'name': 'Hebios_Buried_Spawn_Area',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Camp_Barren': {
+    'hash': 56012,
+    'name': 'Hebios_Camp_Barren',
+    'embedded': {}
+  },
+  'Hebios_Camp_Barren_Dynamic': {
+    'hash': 56012,
+    'name': 'Hebios_Camp_Barren_Dynamic',
+    'embedded': {
+      'Closed_Crate_Spawner_26166': {
+        'hash': 26166,
+        'name': 'Closed_Crate_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Enemy_Spawn_30256': {
+        'hash': 30256,
+        'name': 'Enemy_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Hebios_Camp_Barren_Dynamic_53304': {
+        'hash': 53304,
+        'name': 'Hebios_Camp_Barren_Dynamic',
+        'savables': {}
+      },
+      'Hebios_Camp_Fire_Spawner_55752': {
+        'hash': 55752,
+        'name': 'Hebios_Camp_Fire_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Open_Crate_Spawner_48408': {
+        'hash': 48408,
+        'name': 'Open_Crate_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Camp_Spawner': {
+    'hash': 43300,
+    'name': 'Hebios_Camp_Spawner',
+    'embedded': {}
+  },
+  'Hebios_Camp_Valley': {
+    'hash': 42062,
+    'name': 'Hebios_Camp_Valley',
+    'embedded': {
+      'Hebios_Camp_Valley_38962': {
+        'hash': 38962,
+        'name': 'Hebios_Camp_Valley',
+        'savables': {
+          'StaticGenerationParent': {
+            'hash': 2975913730,
+            'name': 'StaticGenerationParent'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Camp_Valley_Center_Section_NEW': {
+    'hash': 5350,
+    'name': 'Hebios_Camp_Valley_Center_Section_NEW',
+    'embedded': {}
+  },
+  'Hebios_Camp_Valley_Center_Section_Pond': {
+    'hash': 54680,
+    'name': 'Hebios_Camp_Valley_Center_Section_Pond',
+    'embedded': {}
+  },
+  'Hebios_Camp_Valley_Front_Section_Spike_Gate': {
+    'hash': 42358,
+    'name': 'Hebios_Camp_Valley_Front_Section_Spike_Gate',
+    'embedded': {}
+  },
+  'Hebios_Camp_Valley_Front_Section_Stone_Cliff': {
+    'hash': 19412,
+    'name': 'Hebios_Camp_Valley_Front_Section_Stone_Cliff',
+    'embedded': {}
+  },
+  'Hebios_Camp_Valley_Left_Section_Archway': {
+    'hash': 40482,
+    'name': 'Hebios_Camp_Valley_Left_Section_Archway',
+    'embedded': {}
+  },
+  'Hebios_Camp_Valley_Left_Section_Hilly_Forest': {
+    'hash': 37966,
+    'name': 'Hebios_Camp_Valley_Left_Section_Hilly_Forest',
+    'embedded': {}
+  },
+  'Hebios_Closed_Crate_Spawner': {
+    'hash': 46524,
+    'name': 'Hebios_Closed_Crate_Spawner',
+    'embedded': {
+      'Hebios_Closed_Crate_Spawner_19058': {
+        'hash': 19058,
+        'name': 'Hebios_Closed_Crate_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Crafted_Mould': {
+    'hash': 22498,
+    'name': 'Hebios_Crafted_Mould',
+    'embedded': {
+      'Hebios_Crafted_Mould_14710': {
+        'hash': 14710,
+        'name': 'Hebios_Crafted_Mould',
+        'savables': {
+          'Mould': {
+            'hash': 391977879,
+            'name': 'Mould'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'hebios_mould_centerFrame_grp_18498': {
+        'hash': 18498,
+        'name': 'hebios_mould_centerFrame_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_emblem_grp_9986': {
+        'hash': 9986,
+        'name': 'hebios_mould_emblem_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_frame_horizontal_grp_01_18458': {
+        'hash': 18458,
+        'name': 'hebios_mould_frame_horizontal_grp_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_frame_horizontal_grp_02_18482': {
+        'hash': 18482,
+        'name': 'hebios_mould_frame_horizontal_grp_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_frame_vertical_grp_01_18462': {
+        'hash': 18462,
+        'name': 'hebios_mould_frame_vertical_grp_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_frame_vertical_grp_02_18486': {
+        'hash': 18486,
+        'name': 'hebios_mould_frame_vertical_grp_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_grassKnot_grp_01_18450': {
+        'hash': 18450,
+        'name': 'hebios_mould_grassKnot_grp_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_grassKnot_grp_02_18446': {
+        'hash': 18446,
+        'name': 'hebios_mould_grassKnot_grp_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_grassKnot_grp_03_18502': {
+        'hash': 18502,
+        'name': 'hebios_mould_grassKnot_grp_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_grassKnot_grp_04_18474': {
+        'hash': 18474,
+        'name': 'hebios_mould_grassKnot_grp_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_ingotGraphic_grp_18494': {
+        'hash': 18494,
+        'name': 'hebios_mould_ingotGraphic_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_railSlot_grp_01_18490': {
+        'hash': 18490,
+        'name': 'hebios_mould_railSlot_grp_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_railSlot_grp_02_18454': {
+        'hash': 18454,
+        'name': 'hebios_mould_railSlot_grp_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_railSlot_grp_03_18470': {
+        'hash': 18470,
+        'name': 'hebios_mould_railSlot_grp_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_railSlot_grp_04_18466': {
+        'hash': 18466,
+        'name': 'hebios_mould_railSlot_grp_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_mould_timesGraphic_grp_18478': {
+        'hash': 18478,
+        'name': 'hebios_mould_timesGraphic_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'katana_guard_grp_63702': {
+        'hash': 63702,
+        'name': 'katana_guard_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'redwood_gotera_core_emblemPart_grp_52708': {
+        'hash': 52708,
+        'name': 'redwood_gotera_core_emblemPart_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'redwood_gotera_core_leafPart_grp_52712': {
+        'hash': 52712,
+        'name': 'redwood_gotera_core_leafPart_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Guard': {
+    'hash': 5144,
+    'name': 'Hebios_Guard',
+    'embedded': {
+      'Heat_Point_Collection_56294': {
+        'hash': 56294,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Hebios_Guard_36330': {
+        'hash': 36330,
+        'name': 'Hebios_Guard',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Insert_SwordType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Craft',
+        'savables': {}
+      },
+      'Slot_SwordType_39370': {
+        'hash': 39370,
+        'name': 'Slot_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Hebios_Handle_Katana': {
+    'hash': 53200,
+    'name': 'Hebios_Handle_Katana',
+    'embedded': {
+      'Hebios_Handle_Katana_40148': {
+        'hash': 40148,
+        'name': 'Hebios_Handle_Katana',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Enchantable': {
+            'hash': 4134534481,
+            'name': 'Enchantable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Joint_Group_SwordType_63178': {
+        'hash': 63178,
+        'name': 'Joint_Group_SwordType',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_53492': {
+        'hash': 53492,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63318': {
+        'hash': 63318,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      }
+    }
+  },
+  'Hebios_Handle_Kunai': {
+    'hash': 18456,
+    'name': 'Hebios_Handle_Kunai',
+    'embedded': {
+      'Hebios_Handle_Kunai_14986': {
+        'hash': 14986,
+        'name': 'Hebios_Handle_Kunai',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Multi_6136': {
+        'hash': 6136,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Hebios_Handle_Naginata': {
+    'hash': 24220,
+    'name': 'Hebios_Handle_Naginata',
+    'embedded': {
+      'Hebios_Handle_Naginata_26368': {
+        'hash': 26368,
+        'name': 'Hebios_Handle_Naginata',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Enchantable': {
+            'hash': 4134534481,
+            'name': 'Enchantable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_EdgeType_Craft_53692': {
+        'hash': 53692,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_53060': {
+        'hash': 53060,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_63218': {
+        'hash': 63218,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63270': {
+        'hash': 63270,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      }
+    }
+  },
+  'Hebios_Handle_Wakizashi': {
+    'hash': 47662,
+    'name': 'Hebios_Handle_Wakizashi',
+    'embedded': {
+      'Hebios_Handle_Wakizashi_47666': {
+        'hash': 47666,
+        'name': 'Hebios_Handle_Wakizashi',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Enchantable': {
+            'hash': 4134534481,
+            'name': 'Enchantable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Joint_Group_SwordType_63178': {
+        'hash': 63178,
+        'name': 'Joint_Group_SwordType',
+        'savables': {}
+      },
+      'Slot_Straight_Short_Sword_Type_63318': {
+        'hash': 63318,
+        'name': 'Slot_Straight_Short_Sword_Type',
+        'savables': {}
+      }
+    }
+  },
+  'Hebios_Katana_Blade_Part_01': {
+    'hash': 12388,
+    'name': 'Hebios_Katana_Blade_Part_01',
+    'embedded': {
+      'Hebios_Katana_Blade_Part_01_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Katana_Blade_Part_01',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Katana_Blade_Part_02': {
+    'hash': 12386,
+    'name': 'Hebios_Katana_Blade_Part_02',
+    'embedded': {
+      'Hebios_Katana_Blade_Part_02_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Katana_Blade_Part_02',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Katana_Blade_Part_Full': {
+    'hash': 17266,
+    'name': 'Hebios_Katana_Blade_Part_Full',
+    'embedded': {
+      'Hebios_Katana_Blade_Part_Full_40924': {
+        'hash': 40924,
+        'name': 'Hebios_Katana_Blade_Part_Full',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'hebios_katana_blade_part_01_56656': {
+        'hash': 56656,
+        'name': 'hebios_katana_blade_part_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_katana_blade_part_02_56652': {
+        'hash': 56652,
+        'name': 'hebios_katana_blade_part_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Naginata_Blade_Part_01': {
+    'hash': 17238,
+    'name': 'Hebios_Naginata_Blade_Part_01',
+    'embedded': {
+      'Hebios_Naginata_Blade_Part_01_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Naginata_Blade_Part_01',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Naginata_Blade_Part_02': {
+    'hash': 42894,
+    'name': 'Hebios_Naginata_Blade_Part_02',
+    'embedded': {
+      'Hebios_Naginata_Blade_Part_02_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Naginata_Blade_Part_02',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Naginata_Blade_Part_Full': {
+    'hash': 17420,
+    'name': 'Hebios_Naginata_Blade_Part_Full',
+    'embedded': {
+      'Hebios_Naginata_Blade_Part_Full_40924': {
+        'hash': 40924,
+        'name': 'Hebios_Naginata_Blade_Part_Full',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'naginata_blade_part_01_grp_21404': {
+        'hash': 21404,
+        'name': 'naginata_blade_part_01_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'naginata_blade_part_02_grp_21408': {
+        'hash': 21408,
+        'name': 'naginata_blade_part_02_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Open_Crate_Spawner': {
+    'hash': 46522,
+    'name': 'Hebios_Open_Crate_Spawner',
+    'embedded': {
+      'Hebios_Open_Crate_Spawner_19060': {
+        'hash': 19060,
+        'name': 'Hebios_Open_Crate_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Sai_Blade_Part_01': {
+    'hash': 57048,
+    'name': 'Hebios_Sai_Blade_Part_01',
+    'embedded': {
+      'Hebios_Sai_Blade_Part_01_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Sai_Blade_Part_01',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Sai_Blade_Part_02': {
+    'hash': 56830,
+    'name': 'Hebios_Sai_Blade_Part_02',
+    'embedded': {
+      'Hebios_Sai_Blade_Part_02_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Sai_Blade_Part_02',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Sai_Blade_Part_Full': {
+    'hash': 1600,
+    'name': 'Hebios_Sai_Blade_Part_Full',
+    'embedded': {
+      'Hebios_Sai_Blade_Part_Full_40924': {
+        'hash': 40924,
+        'name': 'Hebios_Sai_Blade_Part_Full',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'hebios_sai_blade_part_01_50732': {
+        'hash': 50732,
+        'name': 'hebios_sai_blade_part_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hebios_sai_blade_part_02_50728': {
+        'hash': 50728,
+        'name': 'hebios_sai_blade_part_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Storage_Chest': {
+    'hash': 44984,
+    'name': 'Hebios_Storage_Chest',
+    'embedded': {
+      'Bottom_Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Bottom_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_2_2778': {
+        'hash': 2778,
+        'name': 'Bottom_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_3_2776': {
+        'hash': 2776,
+        'name': 'Bottom_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_4_2770': {
+        'hash': 2770,
+        'name': 'Bottom_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_5_2772': {
+        'hash': 2772,
+        'name': 'Bottom_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_6_2774': {
+        'hash': 2774,
+        'name': 'Bottom_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Left_23970': {
+        'hash': 23970,
+        'name': 'Handle_Left',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_Right_23964': {
+        'hash': 23964,
+        'name': 'Handle_Right',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Hebios_Storage_Chest_2788': {
+        'hash': 2788,
+        'name': 'Hebios_Storage_Chest',
+        'savables': {
+          'Chest': {
+            'hash': 3598052397,
+            'name': 'Chest'
+          }
+        }
+      },
+      'Lid_2768': {
+        'hash': 2768,
+        'name': 'Lid',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Loot_Module_27674': {
+        'hash': 27674,
+        'name': 'Loot_Module',
+        'savables': {
+          'LootModule': {
+            'hash': 634164392,
+            'name': 'LootModule'
+          }
+        }
+      },
+      'Top_Dock_1_2766': {
+        'hash': 2766,
+        'name': 'Top_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_2_2764': {
+        'hash': 2764,
+        'name': 'Top_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_3_2762': {
+        'hash': 2762,
+        'name': 'Top_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_4_2756': {
+        'hash': 2756,
+        'name': 'Top_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_5_2758': {
+        'hash': 2758,
+        'name': 'Top_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_6_2760': {
+        'hash': 2760,
+        'name': 'Top_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Storage_Chest_Climbing': {
+    'hash': 35078,
+    'name': 'Hebios_Storage_Chest_Climbing',
+    'embedded': {
+      'Bottom_Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Bottom_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_2_2778': {
+        'hash': 2778,
+        'name': 'Bottom_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_3_2776': {
+        'hash': 2776,
+        'name': 'Bottom_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_4_2770': {
+        'hash': 2770,
+        'name': 'Bottom_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_5_2772': {
+        'hash': 2772,
+        'name': 'Bottom_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_6_2774': {
+        'hash': 2774,
+        'name': 'Bottom_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Left_23970': {
+        'hash': 23970,
+        'name': 'Handle_Left',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_Right_23964': {
+        'hash': 23964,
+        'name': 'Handle_Right',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Hebios_Storage_Chest_Climbing_35076': {
+        'hash': 35076,
+        'name': 'Hebios_Storage_Chest_Climbing',
+        'savables': {
+          'Chest': {
+            'hash': 3598052397,
+            'name': 'Chest'
+          }
+        }
+      },
+      'Lid_2768': {
+        'hash': 2768,
+        'name': 'Lid',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Loot_Module_27674': {
+        'hash': 27674,
+        'name': 'Loot_Module',
+        'savables': {
+          'LootModule': {
+            'hash': 634164392,
+            'name': 'LootModule'
+          }
+        }
+      },
+      'Top_Dock_1_2766': {
+        'hash': 2766,
+        'name': 'Top_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_2_2764': {
+        'hash': 2764,
+        'name': 'Top_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_3_2762': {
+        'hash': 2762,
+        'name': 'Top_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_4_2756': {
+        'hash': 2756,
+        'name': 'Top_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_5_2758': {
+        'hash': 2758,
+        'name': 'Top_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_6_2760': {
+        'hash': 2760,
+        'name': 'Top_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Storage_Chest_Gcore': {
+    'hash': 31618,
+    'name': 'Hebios_Storage_Chest_Gcore',
+    'embedded': {
+      'Bottom_Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Bottom_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_2_2778': {
+        'hash': 2778,
+        'name': 'Bottom_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_3_2776': {
+        'hash': 2776,
+        'name': 'Bottom_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_4_2770': {
+        'hash': 2770,
+        'name': 'Bottom_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_5_2772': {
+        'hash': 2772,
+        'name': 'Bottom_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_6_2774': {
+        'hash': 2774,
+        'name': 'Bottom_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Left_23970': {
+        'hash': 23970,
+        'name': 'Handle_Left',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_Right_23964': {
+        'hash': 23964,
+        'name': 'Handle_Right',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Hebios_Storage_Chest_Gcore_2788': {
+        'hash': 2788,
+        'name': 'Hebios_Storage_Chest_Gcore',
+        'savables': {
+          'Chest': {
+            'hash': 3598052397,
+            'name': 'Chest'
+          }
+        }
+      },
+      'Lid_2768': {
+        'hash': 2768,
+        'name': 'Lid',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Loot_Module_27674': {
+        'hash': 27674,
+        'name': 'Loot_Module',
+        'savables': {
+          'LootModule': {
+            'hash': 634164392,
+            'name': 'LootModule'
+          }
+        }
+      },
+      'Top_Dock_1_2766': {
+        'hash': 2766,
+        'name': 'Top_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_2_2764': {
+        'hash': 2764,
+        'name': 'Top_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_3_2762': {
+        'hash': 2762,
+        'name': 'Top_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_4_2756': {
+        'hash': 2756,
+        'name': 'Top_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_5_2758': {
+        'hash': 2758,
+        'name': 'Top_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_6_2760': {
+        'hash': 2760,
+        'name': 'Top_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Wakizashi_Blade_Part_01': {
+    'hash': 49774,
+    'name': 'Hebios_Wakizashi_Blade_Part_01',
+    'embedded': {
+      'Hebios_Wakizashi_Blade_Part_01_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Wakizashi_Blade_Part_01',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Wakizashi_Blade_Part_02': {
+    'hash': 50184,
+    'name': 'Hebios_Wakizashi_Blade_Part_02',
+    'embedded': {
+      'Hebios_Wakizashi_Blade_Part_02_46162': {
+        'hash': 46162,
+        'name': 'Hebios_Wakizashi_Blade_Part_02',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Hebios_Wakizashi_Blade_Part_Full': {
+    'hash': 9018,
+    'name': 'Hebios_Wakizashi_Blade_Part_Full',
+    'embedded': {
+      'Hebios_Wakizashi_Blade_Part_Full_40924': {
+        'hash': 40924,
+        'name': 'Hebios_Wakizashi_Blade_Part_Full',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'wakizashi_blade_part_01_grp_31190': {
+        'hash': 31190,
+        'name': 'wakizashi_blade_part_01_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wakizashi_blade_part_02_grp_31194': {
+        'hash': 31194,
+        'name': 'wakizashi_blade_part_02_grp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Hitting_Short_Sword_Training': {
+    'hash': 55646,
+    'name': 'Hitting_Short_Sword_Training',
+    'embedded': {
+      'Blade_1152': {
+        'hash': 1152,
+        'name': 'Blade',
+        'savables': {}
+      },
+      'Hitting_Short_Sword_Training_1152': {
+        'hash': 1152,
+        'name': 'Hitting_Short_Sword_Training',
+        'savables': {}
+      }
+    }
+  },
+  'Hoarder_Bag': {
+    'hash': 54214,
+    'name': 'Hoarder_Bag',
+    'embedded': {
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Dock_(1)_47074': {
+        'hash': 47074,
+        'name': 'Dock_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_464': {
+        'hash': 464,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BL_(1)_1146': {
+        'hash': 1146,
+        'name': 'Dock_BL_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BL_42978': {
+        'hash': 42978,
+        'name': 'Dock_BL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BM_(1)_1148': {
+        'hash': 1148,
+        'name': 'Dock_BM_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BM_42976': {
+        'hash': 42976,
+        'name': 'Dock_BM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BR_(1)_1432': {
+        'hash': 1432,
+        'name': 'Dock_BR_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BR_(2)_1240': {
+        'hash': 1240,
+        'name': 'Dock_BR_(2)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BR_(3)_1150': {
+        'hash': 1150,
+        'name': 'Dock_BR_(3)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_BR_42974': {
+        'hash': 42974,
+        'name': 'Dock_BR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_ML_42984': {
+        'hash': 42984,
+        'name': 'Dock_ML',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MM_42982': {
+        'hash': 42982,
+        'name': 'Dock_MM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MR_(1)_1430': {
+        'hash': 1430,
+        'name': 'Dock_MR_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MR_42980': {
+        'hash': 42980,
+        'name': 'Dock_MR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TL_42990': {
+        'hash': 42990,
+        'name': 'Dock_TL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TM_42988': {
+        'hash': 42988,
+        'name': 'Dock_TM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TR_(1)_1428': {
+        'hash': 1428,
+        'name': 'Dock_TR_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TR_42986': {
+        'hash': 42986,
+        'name': 'Dock_TR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Hoarder_Bag_43012': {
+        'hash': 43012,
+        'name': 'Hoarder_Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Bag_Attach_10614': {
+        'hash': 10614,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_10616': {
+        'hash': 10616,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_30776': {
+        'hash': 30776,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_55164': {
+        'hash': 55164,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Pin_Collectible_Attach_59540': {
+        'hash': 59540,
+        'name': 'Slot_Bag_Pin_Collectible_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Tool_Attachment_1020': {
+        'hash': 1020,
+        'name': 'Slot_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'Slot_Bag_Tool_Attachment_918': {
+        'hash': 918,
+        'name': 'Slot_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'hoarder_bag_body_39890': {
+        'hash': 39890,
+        'name': 'hoarder_bag_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_clasp_front_L_39810': {
+        'hash': 39810,
+        'name': 'hoarder_bag_clasp_front_L',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_clasp_front_R_39850': {
+        'hash': 39850,
+        'name': 'hoarder_bag_clasp_front_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_flap_39878': {
+        'hash': 39878,
+        'name': 'hoarder_bag_flap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_flap_clasp_39886': {
+        'hash': 39886,
+        'name': 'hoarder_bag_flap_clasp',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_01_39894': {
+        'hash': 39894,
+        'name': 'hoarder_bag_pin_L_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_02_39882': {
+        'hash': 39882,
+        'name': 'hoarder_bag_pin_L_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_03_39930': {
+        'hash': 39930,
+        'name': 'hoarder_bag_pin_L_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_04_39826': {
+        'hash': 39826,
+        'name': 'hoarder_bag_pin_L_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_05_39898': {
+        'hash': 39898,
+        'name': 'hoarder_bag_pin_L_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_06_39834': {
+        'hash': 39834,
+        'name': 'hoarder_bag_pin_L_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_L_07_39902': {
+        'hash': 39902,
+        'name': 'hoarder_bag_pin_L_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_01_39870': {
+        'hash': 39870,
+        'name': 'hoarder_bag_pin_R_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_02_39858': {
+        'hash': 39858,
+        'name': 'hoarder_bag_pin_R_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_03_39914': {
+        'hash': 39914,
+        'name': 'hoarder_bag_pin_R_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_04_39926': {
+        'hash': 39926,
+        'name': 'hoarder_bag_pin_R_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_05_39806': {
+        'hash': 39806,
+        'name': 'hoarder_bag_pin_R_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_06_39874': {
+        'hash': 39874,
+        'name': 'hoarder_bag_pin_R_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_pin_R_07_39814': {
+        'hash': 39814,
+        'name': 'hoarder_bag_pin_R_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_sideBuckle_L_01_39830': {
+        'hash': 39830,
+        'name': 'hoarder_bag_sideBuckle_L_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_sideBuckle_L_02_39802': {
+        'hash': 39802,
+        'name': 'hoarder_bag_sideBuckle_L_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_sideBuckle_R_01_39866': {
+        'hash': 39866,
+        'name': 'hoarder_bag_sideBuckle_R_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_sideBuckle_R_02_39906': {
+        'hash': 39906,
+        'name': 'hoarder_bag_sideBuckle_R_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_body_39822': {
+        'hash': 39822,
+        'name': 'hoarder_bag_strap_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_bottom_L_39854': {
+        'hash': 39854,
+        'name': 'hoarder_bag_strap_bottom_L',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_bottom_R_39798': {
+        'hash': 39798,
+        'name': 'hoarder_bag_strap_bottom_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_front_L_39838': {
+        'hash': 39838,
+        'name': 'hoarder_bag_strap_front_L',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_front_R_39818': {
+        'hash': 39818,
+        'name': 'hoarder_bag_strap_front_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_slot_L_39862': {
+        'hash': 39862,
+        'name': 'hoarder_bag_strap_slot_L',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_slot_R_39846': {
+        'hash': 39846,
+        'name': 'hoarder_bag_strap_slot_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_top_buckle_L_39922': {
+        'hash': 39922,
+        'name': 'hoarder_bag_strap_top_buckle_L',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_strap_top_buckle_R_39918': {
+        'hash': 39918,
+        'name': 'hoarder_bag_strap_top_buckle_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_topDetail_01_39910': {
+        'hash': 39910,
+        'name': 'hoarder_bag_topDetail_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'hoarder_bag_topDetail_02_39842': {
+        'hash': 39842,
+        'name': 'hoarder_bag_topDetail_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_handle_body_14308': {
+        'hash': 14308,
+        'name': 'standard_bag_handle_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_handle_wraps_14304': {
+        'hash': 14304,
+        'name': 'standard_bag_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'HolidayRewardDisplay': {
+    'hash': 32158,
+    'name': 'HolidayRewardDisplay',
+    'embedded': {
+      'HolidayRewardDisplay_32140': {
+        'hash': 32140,
+        'name': 'HolidayRewardDisplay',
+        'savables': {}
+      }
+    }
+  },
+  'Hot_Coalbed': {
+    'hash': 41234,
+    'name': 'Hot_Coalbed',
+    'embedded': {
+      'Heating_Bit_26176': {
+        'hash': 26176,
+        'name': 'Heating_Bit',
+        'savables': {}
+      },
+      'Hot_Coalbed_26204': {
+        'hash': 26204,
+        'name': 'Hot_Coalbed',
+        'savables': {}
+      },
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Hover_Piece': {
+    'hash': 50934,
+    'name': 'Hover_Piece',
+    'embedded': {
+      'Hover_Piece_5676': {
+        'hash': 5676,
+        'name': 'Hover_Piece',
+        'savables': {}
+      }
+    }
+  },
+  'Infinite_Fire': {
+    'hash': 5172,
+    'name': 'Infinite_Fire',
+    'embedded': {
+      'Fire_8488': {
+        'hash': 8488,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          }
+        }
+      },
+      'Infinite_Fire_24372': {
+        'hash': 24372,
+        'name': 'Infinite_Fire',
+        'savables': {
+          'BasicDecay': {
+            'hash': 3801256786,
+            'name': 'BasicDecay'
+          }
+        }
+      },
+      'Spawner_49628': {
+        'hash': 49628,
+        'name': 'Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Info_Board': {
+    'hash': 51114,
+    'name': 'Info_Board',
+    'embedded': {
+      'Info_Board_63822': {
+        'hash': 63822,
+        'name': 'Info_Board',
+        'savables': {
+          'InfoBoard': {
+            'hash': 3431876266,
+            'name': 'InfoBoard'
+          }
+        }
+      }
+    }
+  },
+  'Ingredient_Generator_Shelf': {
+    'hash': 51096,
+    'name': 'Ingredient_Generator_Shelf',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58082': {
+        'hash': 58082,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58084': {
+        'hash': 58084,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58086': {
+        'hash': 58086,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58088': {
+        'hash': 58088,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58090': {
+        'hash': 58090,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58092': {
+        'hash': 58092,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58094': {
+        'hash': 58094,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58096': {
+        'hash': 58096,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58098': {
+        'hash': 58098,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Ingredient_Generator_Shelf_51098': {
+        'hash': 51098,
+        'name': 'Ingredient_Generator_Shelf',
+        'savables': {}
+      },
+      'Recipe_Dock_60388': {
+        'hash': 60388,
+        'name': 'Recipe_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Int_Range_Operator': {
+    'hash': 55740,
+    'name': 'Int_Range_Operator',
+    'embedded': {
+      'Int_Range_Operator_13344': {
+        'hash': 13344,
+        'name': 'Int_Range_Operator',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntRangeReceiver': {
+            'hash': 2610542999,
+            'name': 'LogicIntRangeReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Iron_Boulder': {
+    'hash': 45344,
+    'name': 'Iron_Boulder',
+    'embedded': {
+      'Iron_Boulder_49644': {
+        'hash': 49644,
+        'name': 'Iron_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_48914': {
+        'hash': 48914,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Iron_Boulder_Parts': {
+    'hash': 18070,
+    'name': 'Iron_Boulder_Parts',
+    'embedded': {
+      'Iron_Boulder_Part_01_64822': {
+        'hash': 64822,
+        'name': 'Iron_Boulder_Part_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Iron_Boulder_Part_02_64818': {
+        'hash': 64818,
+        'name': 'Iron_Boulder_Part_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Iron_Boulder_Part_03_64806': {
+        'hash': 64806,
+        'name': 'Iron_Boulder_Part_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Iron_Boulder_Part_04_64814': {
+        'hash': 64814,
+        'name': 'Iron_Boulder_Part_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Iron_Boulder_Part_05_64810': {
+        'hash': 64810,
+        'name': 'Iron_Boulder_Part_05',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Iron_Boulder_Part_06_64826': {
+        'hash': 64826,
+        'name': 'Iron_Boulder_Part_06',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Iron_Boulder_Parts_64778': {
+        'hash': 64778,
+        'name': 'Iron_Boulder_Parts',
+        'savables': {}
+      }
+    }
+  },
+  'Iron_Boulder_Training': {
+    'hash': 10140,
+    'name': 'Iron_Boulder_Training',
+    'embedded': {
+      'Iron_Boulder_Training_10130': {
+        'hash': 10130,
+        'name': 'Iron_Boulder_Training',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_48914': {
+        'hash': 48914,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Iron_Cluster': {
+    'hash': 28272,
+    'name': 'Iron_Cluster',
+    'embedded': {
+      'Iron_Cluster_18314': {
+        'hash': 18314,
+        'name': 'Iron_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Iron_Ingot': {
+    'hash': 23012,
+    'name': 'Iron_Ingot',
+    'embedded': {
+      'Heat_Point_Collection_13170': {
+        'hash': 13170,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Iron_Ingot_22900': {
+        'hash': 22900,
+        'name': 'Iron_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Iron_Ore': {
+    'hash': 61652,
+    'name': 'Iron_Ore',
+    'embedded': {
+      'Iron_Ore_37686': {
+        'hash': 37686,
+        'name': 'Iron_Ore',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Ka_Karimata_Arrow': {
+    'hash': 960,
+    'name': 'Ka_Karimata_Arrow',
+    'embedded': {
+      'Ka_Karimata_Arrow_43746': {
+        'hash': 43746,
+        'name': 'Ka_Karimata_Arrow',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Tip_58698': {
+        'hash': 58698,
+        'name': 'Tip',
+        'savables': {}
+      }
+    }
+  },
+  'Katana': {
+    'hash': 34994,
+    'name': 'Katana',
+    'embedded': {
+      'Katana_36330': {
+        'hash': 36330,
+        'name': 'Katana',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Enchantable': {
+            'hash': 4134534481,
+            'name': 'Enchantable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Key_Standard': {
+    'hash': 39744,
+    'name': 'Key_Standard',
+    'embedded': {
+      'Key_Standard_26420': {
+        'hash': 26420,
+        'name': 'Key_Standard',
+        'savables': {
+          'KeyItem': {
+            'hash': 414036426,
+            'name': 'KeyItem'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Kunai': {
+    'hash': 32002,
+    'name': 'Kunai',
+    'embedded': {
+      'Kunai_36330': {
+        'hash': 36330,
+        'name': 'Kunai',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Embeddable': {
+            'hash': 22446553,
+            'name': 'Embeddable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Ladder': {
+    'hash': 56168,
+    'name': 'Ladder',
+    'embedded': {
+      'Ladder_53890': {
+        'hash': 53890,
+        'name': 'Ladder',
+        'savables': {}
+      }
+    }
+  },
+  'Lantern': {
+    'hash': 41760,
+    'name': 'Lantern',
+    'embedded': {
+      'Fire_54948': {
+        'hash': 54948,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Fuel_Dock_63110': {
+        'hash': 63110,
+        'name': 'Fuel_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Lantern_56450': {
+        'hash': 56450,
+        'name': 'Lantern',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'lantern_arm_28726': {
+        'hash': 28726,
+        'name': 'lantern_arm',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_01_28734': {
+        'hash': 28734,
+        'name': 'lantern_bar_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_02_28742': {
+        'hash': 28742,
+        'name': 'lantern_bar_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_03_28770': {
+        'hash': 28770,
+        'name': 'lantern_bar_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_04_28766': {
+        'hash': 28766,
+        'name': 'lantern_bar_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_05_28738': {
+        'hash': 28738,
+        'name': 'lantern_bar_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_06_28778': {
+        'hash': 28778,
+        'name': 'lantern_bar_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_bar_07_28750': {
+        'hash': 28750,
+        'name': 'lantern_bar_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_base_28746': {
+        'hash': 28746,
+        'name': 'lantern_base',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_face_28754': {
+        'hash': 28754,
+        'name': 'lantern_face',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_handle_28758': {
+        'hash': 28758,
+        'name': 'lantern_handle',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_topCap_28762': {
+        'hash': 28762,
+        'name': 'lantern_topCap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_topSwivel_28774': {
+        'hash': 28774,
+        'name': 'lantern_topSwivel',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'lantern_visor_28730': {
+        'hash': 28730,
+        'name': 'lantern_visor',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Large_Cave_Mushroom': {
+    'hash': 29690,
+    'name': 'Large_Cave_Mushroom',
+    'embedded': {
+      'Large_Cave_Mushroom_30160': {
+        'hash': 30160,
+        'name': 'Large_Cave_Mushroom',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Large_Cave_Mushroom_Body_30160': {
+        'hash': 30160,
+        'name': 'Large_Cave_Mushroom_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Spawner_26386': {
+        'hash': 26386,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'cave_mushroom_headEnd_jnt_22906': {
+        'hash': 22906,
+        'name': 'cave_mushroom_headEnd_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'cave_mushroom_spine_jnt_27926': {
+        'hash': 27926,
+        'name': 'cave_mushroom_spine_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Large_Cave_Mushroom_Cluster': {
+    'hash': 2422,
+    'name': 'Large_Cave_Mushroom_Cluster',
+    'embedded': {
+      'Large_Cave_Mushroom_Cluster_61380': {
+        'hash': 61380,
+        'name': 'Large_Cave_Mushroom_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Large_Cave_Mushroom_OLD': {
+    'hash': 36866,
+    'name': 'Large_Cave_Mushroom_OLD',
+    'embedded': {
+      'Large_Cave_Mushroom_OLD_30160': {
+        'hash': 30160,
+        'name': 'Large_Cave_Mushroom_OLD',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawner_26386': {
+        'hash': 26386,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'cave_mushroom_headEnd_jnt_22906': {
+        'hash': 22906,
+        'name': 'cave_mushroom_headEnd_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'cave_mushroom_spine_jnt_27926': {
+        'hash': 27926,
+        'name': 'cave_mushroom_spine_jnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Large_Guard_Rectangle': {
+    'hash': 9304,
+    'name': 'Large_Guard_Rectangle',
+    'embedded': {
+      'Heat_Point_Collection_57820': {
+        'hash': 57820,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Large_SwordType_Craft_51894': {
+        'hash': 51894,
+        'name': 'Insert_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Large_Guard_Rectangle_51938': {
+        'hash': 51938,
+        'name': 'Large_Guard_Rectangle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Large_SwordType_51896': {
+        'hash': 51896,
+        'name': 'Slot_Large_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Large_Guard_TShape': {
+    'hash': 23552,
+    'name': 'Large_Guard_TShape',
+    'embedded': {
+      'Heat_Point_Collection_58132': {
+        'hash': 58132,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Large_SwordType_Craft_23506': {
+        'hash': 23506,
+        'name': 'Insert_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Large_Guard_TShape_23550': {
+        'hash': 23550,
+        'name': 'Large_Guard_TShape',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Large_SwordType_23508': {
+        'hash': 23508,
+        'name': 'Slot_Large_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Large_Guard_Wedge': {
+    'hash': 39010,
+    'name': 'Large_Guard_Wedge',
+    'embedded': {
+      'Heat_Point_Collection_58440': {
+        'hash': 58440,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Large_SwordType_Craft_38964': {
+        'hash': 38964,
+        'name': 'Insert_Large_SwordType_Craft',
+        'savables': {}
+      },
+      'Large_Guard_Wedge_39008': {
+        'hash': 39008,
+        'name': 'Large_Guard_Wedge',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Large_SwordType_38966': {
+        'hash': 38966,
+        'name': 'Slot_Large_SwordType',
+        'savables': {}
+      }
+    }
+  },
+  'Large_Longsword_Blade': {
+    'hash': 56124,
+    'name': 'Large_Longsword_Blade',
+    'embedded': {
+      'Heat_Point_Collection_62508': {
+        'hash': 62508,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Large_SwordType_31944': {
+        'hash': 31944,
+        'name': 'Insert_Large_SwordType',
+        'savables': {}
+      },
+      'Large_Longsword_Blade_53840': {
+        'hash': 53840,
+        'name': 'Large_Longsword_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'large_longsword_LOD0_45786': {
+        'hash': 45786,
+        'name': 'large_longsword_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Large_Mythril_Boulder': {
+    'hash': 53902,
+    'name': 'Large_Mythril_Boulder',
+    'embedded': {
+      'Large_Mythril_Boulder_29328': {
+        'hash': 29328,
+        'name': 'Large_Mythril_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_18860': {
+        'hash': 18860,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Large_Spiked_Wooden_Club': {
+    'hash': 55914,
+    'name': 'Large_Spiked_Wooden_Club',
+    'embedded': {
+      'Large_Spiked_Wooden_Club_55724': {
+        'hash': 55724,
+        'name': 'Large_Spiked_Wooden_Club',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Large_Sword': {
+    'hash': 8374,
+    'name': 'Large_Sword',
+    'embedded': {}
+  },
+  'Lava_Pool': {
+    'hash': 34696,
+    'name': 'Lava_Pool',
+    'embedded': {
+      'Heat_Bit_35218': {
+        'hash': 35218,
+        'name': 'Heat_Bit',
+        'savables': {}
+      },
+      'Hurt_Bit_30842': {
+        'hash': 30842,
+        'name': 'Hurt_Bit',
+        'savables': {}
+      },
+      'Lava_Pool_16578': {
+        'hash': 16578,
+        'name': 'Lava_Pool',
+        'savables': {}
+      },
+      'Slow_Bit_34974': {
+        'hash': 34974,
+        'name': 'Slow_Bit',
+        'savables': {}
+      }
+    }
+  },
+  'Leaderboard': {
+    'hash': 44390,
+    'name': 'Leaderboard',
+    'embedded': {
+      'Leaderboard_27564': {
+        'hash': 27564,
+        'name': 'Leaderboard',
+        'savables': {
+          'Leaderboard': {
+            'hash': 3257374625,
+            'name': 'Leaderboard'
+          }
+        }
+      }
+    }
+  },
+  'Lectern': {
+    'hash': 59986,
+    'name': 'Lectern',
+    'embedded': {
+      'Candle_Flame_30100': {
+        'hash': 30100,
+        'name': 'Candle_Flame',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Lectern_57672': {
+        'hash': 57672,
+        'name': 'Lectern',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'BookRestrictor': {
+            'hash': 2629079826,
+            'name': 'BookRestrictor'
+          }
+        }
+      }
+    }
+  },
+  'Lectern_Flat': {
+    'hash': 45828,
+    'name': 'Lectern_Flat',
+    'embedded': {
+      'Lectern_Flat_45826': {
+        'hash': 45826,
+        'name': 'Lectern_Flat',
+        'savables': {}
+      }
+    }
+  },
+  'Leveling_Dummy': {
+    'hash': 44224,
+    'name': 'Leveling_Dummy',
+    'embedded': {
+      'Leveling_Dummy_39942': {
+        'hash': 39942,
+        'name': 'Leveling_Dummy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'dummy_arm_l_01_jnt_46272': {
+        'hash': 46272,
+        'name': 'dummy_arm_l_01_jnt',
+        'savables': {}
+      },
+      'dummy_arm_l_02_jnt_46248': {
+        'hash': 46248,
+        'name': 'dummy_arm_l_02_jnt',
+        'savables': {}
+      },
+      'dummy_arm_l_03_jnt_46250': {
+        'hash': 46250,
+        'name': 'dummy_arm_l_03_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_01_jnt_46246': {
+        'hash': 46246,
+        'name': 'dummy_arm_r_01_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_02_jnt_46254': {
+        'hash': 46254,
+        'name': 'dummy_arm_r_02_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_03_jnt_46256': {
+        'hash': 46256,
+        'name': 'dummy_arm_r_03_jnt',
+        'savables': {}
+      },
+      'dummy_head_01_jnt_46270': {
+        'hash': 46270,
+        'name': 'dummy_head_01_jnt',
+        'savables': {}
+      },
+      'dummy_head_02_jnt_46264': {
+        'hash': 46264,
+        'name': 'dummy_head_02_jnt',
+        'savables': {}
+      },
+      'dummy_head_03_jnt_46262': {
+        'hash': 46262,
+        'name': 'dummy_head_03_jnt',
+        'savables': {}
+      },
+      'dummy_neck_jnt_46268': {
+        'hash': 46268,
+        'name': 'dummy_neck_jnt',
+        'savables': {}
+      },
+      'dummy_spineMid_jnt_46274': {
+        'hash': 46274,
+        'name': 'dummy_spineMid_jnt',
+        'savables': {}
+      },
+      'dummy_spine_01_jnt_46258': {
+        'hash': 46258,
+        'name': 'dummy_spine_01_jnt',
+        'savables': {}
+      },
+      'dummy_spine_02_jnt_46260': {
+        'hash': 46260,
+        'name': 'dummy_spine_02_jnt',
+        'savables': {}
+      },
+      'dummy_spine_03_jnt_46266': {
+        'hash': 46266,
+        'name': 'dummy_spine_03_jnt',
+        'savables': {}
+      },
+      'dummy_sternum_jnt_46252': {
+        'hash': 46252,
+        'name': 'dummy_sternum_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Lever': {
+    'hash': 27966,
+    'name': 'Lever',
+    'embedded': {}
+  },
+  'LightPuzzle_Test': {
+    'hash': 8524,
+    'name': 'LightPuzzle_Test',
+    'embedded': {}
+  },
+  'Liquid_Pump': {
+    'hash': 39174,
+    'name': 'Liquid_Pump',
+    'embedded': {}
+  },
+  'Lockbox': {
+    'hash': 6974,
+    'name': 'Lockbox',
+    'embedded': {
+      'Chunk_19700': {
+        'hash': 19700,
+        'name': 'Chunk',
+        'savables': {}
+      },
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'Lockbox_9078': {
+        'hash': 9078,
+        'name': 'Lockbox',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Lockbox_Docks': {
+    'hash': 2226,
+    'name': 'Lockbox_Docks',
+    'embedded': {
+      'Bottom_Dock_1_48412': {
+        'hash': 48412,
+        'name': 'Bottom_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_2_48414': {
+        'hash': 48414,
+        'name': 'Bottom_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_3_48416': {
+        'hash': 48416,
+        'name': 'Bottom_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_4_48422': {
+        'hash': 48422,
+        'name': 'Bottom_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_5_48420': {
+        'hash': 48420,
+        'name': 'Bottom_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_6_48418': {
+        'hash': 48418,
+        'name': 'Bottom_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Lockbox_Docks_64298': {
+        'hash': 64298,
+        'name': 'Lockbox_Docks',
+        'savables': {}
+      }
+    }
+  },
+  'Log_Mallet': {
+    'hash': 42518,
+    'name': 'Log_Mallet',
+    'embedded': {}
+  },
+  'Log_Mallet_v02': {
+    'hash': 42030,
+    'name': 'Log_Mallet_v02',
+    'embedded': {}
+  },
+  'LogicBoolOneTimeActivate': {
+    'hash': 28136,
+    'name': 'LogicBoolOneTimeActivate',
+    'embedded': {
+      'LogicBoolOneTimeActivate_28066': {
+        'hash': 28066,
+        'name': 'LogicBoolOneTimeActivate',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  'LogicFloatChangeOnBool': {
+    'hash': 62220,
+    'name': 'LogicFloatChangeOnBool',
+    'embedded': {
+      'LogicFloatChangeOnBool_56894': {
+        'hash': 56894,
+        'name': 'LogicFloatChangeOnBool',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicFloatChangeOnBool': {
+            'hash': 200292695,
+            'name': 'LogicFloatChangeOnBool'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          }
+        }
+      }
+    }
+  },
+  'LogicFloatReset': {
+    'hash': 57100,
+    'name': 'LogicFloatReset',
+    'embedded': {
+      'LogicFloatReset_56894': {
+        'hash': 56894,
+        'name': 'LogicFloatReset',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'LogicFloatReset': {
+            'hash': 3245685963,
+            'name': 'LogicFloatReset'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          }
+        }
+      }
+    }
+  },
+  'LogicReset': {
+    'hash': 36976,
+    'name': 'LogicReset',
+    'embedded': {
+      'LogicReset_42904': {
+        'hash': 42904,
+        'name': 'LogicReset',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicReset': {
+            'hash': 1934129787,
+            'name': 'LogicReset'
+          }
+        }
+      }
+    }
+  },
+  'Logic_Context': {
+    'hash': 34630,
+    'name': 'Logic_Context',
+    'embedded': {
+      'Logic_Context_34154': {
+        'hash': 34154,
+        'name': 'Logic_Context',
+        'savables': {
+          'GlobalLogicManager': {
+            'hash': 967932020,
+            'name': 'GlobalLogicManager'
+          }
+        }
+      }
+    }
+  },
+  'Logic_Int_To_Bool': {
+    'hash': 2454,
+    'name': 'Logic_Int_To_Bool',
+    'embedded': {
+      'Logic_Int_To_Bool_9620': {
+        'hash': 9620,
+        'name': 'Logic_Int_To_Bool',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntReceiver': {
+            'hash': 1081247904,
+            'name': 'LogicIntReceiver'
+          },
+          'LogicIntToBool': {
+            'hash': 2253011220,
+            'name': 'LogicIntToBool'
+          }
+        }
+      }
+    }
+  },
+  'Logic_Operator': {
+    'hash': 13390,
+    'name': 'Logic_Operator',
+    'embedded': {
+      'Logic_Operator_13344': {
+        'hash': 13344,
+        'name': 'Logic_Operator',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicGateReceiver': {
+            'hash': 1391720462,
+            'name': 'LogicGateReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Long_S_Hook': {
+    'hash': 20598,
+    'name': 'Long_S_Hook',
+    'embedded': {
+      'Hangable_Dock_5626': {
+        'hash': 5626,
+        'name': 'Hangable_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Long_S_Hook_17940': {
+        'hash': 17940,
+        'name': 'Long_S_Hook',
+        'savables': {}
+      }
+    }
+  },
+  'Loot_Module': {
+    'hash': 29544,
+    'name': 'Loot_Module',
+    'embedded': {}
+  },
+  'MRK_Activation_Line': {
+    'hash': 24096,
+    'name': 'MRK_Activation_Line',
+    'embedded': {
+      'Glow_Ended_44912': {
+        'hash': 44912,
+        'name': 'Glow_Ended',
+        'savables': {}
+      },
+      'Glow_Started_44908': {
+        'hash': 44908,
+        'name': 'Glow_Started',
+        'savables': {}
+      },
+      'MRK_Activation_Line_22336': {
+        'hash': 22336,
+        'name': 'MRK_Activation_Line',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Automated_Pipe_Hazard_Elevator': {
+    'hash': 38546,
+    'name': 'MRK_Automated_Pipe_Hazard_Elevator',
+    'embedded': {
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      },
+      'MRK_Automated_Pipe_Hazard_Elevator_21038': {
+        'hash': 21038,
+        'name': 'MRK_Automated_Pipe_Hazard_Elevator',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Reset_Receiver_17642': {
+        'hash': 17642,
+        'name': 'Reset_Receiver',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'Steam_Spray_61896': {
+        'hash': 61896,
+        'name': 'Steam_Spray',
+        'savables': {}
+      },
+      'Steam_Start_37968': {
+        'hash': 37968,
+        'name': 'Steam_Start',
+        'savables': {}
+      },
+      'mrk_risingPipe_body_20878': {
+        'hash': 20878,
+        'name': 'mrk_risingPipe_body',
+        'savables': {
+          'CurveOutput': {
+            'hash': 2576456808,
+            'name': 'CurveOutput'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Automated_Pipe_Hazard_Elevator_7.6_Variant': {
+    'hash': 61754,
+    'name': 'MRK_Automated_Pipe_Hazard_Elevator_7.6_Variant',
+    'embedded': {
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      },
+      'MRK_Automated_Pipe_Hazard_Elevator_7.6_Variant_21038': {
+        'hash': 21038,
+        'name': 'MRK_Automated_Pipe_Hazard_Elevator_7.6_Variant',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Reset_Receiver_17642': {
+        'hash': 17642,
+        'name': 'Reset_Receiver',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'Steam_Spray_61896': {
+        'hash': 61896,
+        'name': 'Steam_Spray',
+        'savables': {}
+      },
+      'Steam_Start_37968': {
+        'hash': 37968,
+        'name': 'Steam_Start',
+        'savables': {}
+      },
+      'mrk_risingPipe_body_20878': {
+        'hash': 20878,
+        'name': 'mrk_risingPipe_body',
+        'savables': {
+          'CurveOutput': {
+            'hash': 2576456808,
+            'name': 'CurveOutput'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Automated_Pipe_Hazard_Elevator_Large_Inverse_Variant': {
+    'hash': 34664,
+    'name': 'MRK_Automated_Pipe_Hazard_Elevator_Large_Inverse_Variant',
+    'embedded': {
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      },
+      'MRK_Automated_Pipe_Hazard_Elevator_Large_Inverse_Variant_21038': {
+        'hash': 21038,
+        'name': 'MRK_Automated_Pipe_Hazard_Elevator_Large_Inverse_Variant',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Reset_Receiver_17642': {
+        'hash': 17642,
+        'name': 'Reset_Receiver',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'Steam_Spray_61896': {
+        'hash': 61896,
+        'name': 'Steam_Spray',
+        'savables': {}
+      },
+      'Steam_Start_37968': {
+        'hash': 37968,
+        'name': 'Steam_Start',
+        'savables': {}
+      },
+      'mrk_risingPipe_body_20878': {
+        'hash': 20878,
+        'name': 'mrk_risingPipe_body',
+        'savables': {
+          'CurveOutput': {
+            'hash': 2576456808,
+            'name': 'CurveOutput'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Automated_Pipe_Hazard_Elevator_Tall_Variant': {
+    'hash': 37626,
+    'name': 'MRK_Automated_Pipe_Hazard_Elevator_Tall_Variant',
+    'embedded': {
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      },
+      'MRK_Automated_Pipe_Hazard_Elevator_Tall_Variant_21038': {
+        'hash': 21038,
+        'name': 'MRK_Automated_Pipe_Hazard_Elevator_Tall_Variant',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Reset_Receiver_17642': {
+        'hash': 17642,
+        'name': 'Reset_Receiver',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'Steam_Spray_61896': {
+        'hash': 61896,
+        'name': 'Steam_Spray',
+        'savables': {}
+      },
+      'Steam_Start_37968': {
+        'hash': 37968,
+        'name': 'Steam_Start',
+        'savables': {}
+      },
+      'mrk_risingPipe_body_20878': {
+        'hash': 20878,
+        'name': 'mrk_risingPipe_body',
+        'savables': {
+          'CurveOutput': {
+            'hash': 2576456808,
+            'name': 'CurveOutput'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Fuel_Core': {
+    'hash': 65358,
+    'name': 'MRK_Fuel_Core',
+    'embedded': {
+      'MRK_Fuel_Core_63598': {
+        'hash': 63598,
+        'name': 'MRK_Fuel_Core',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Horizontal_Lift': {
+    'hash': 37822,
+    'name': 'MRK_Horizontal_Lift',
+    'embedded': {
+      'MRK_Horizontal_Lift_37846': {
+        'hash': 37846,
+        'name': 'MRK_Horizontal_Lift',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'NetworkedFloatStream': {
+            'hash': 2127962967,
+            'name': 'NetworkedFloatStream'
+          }
+        }
+      },
+      'Platform_57570': {
+        'hash': 57570,
+        'name': 'Platform',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Lantern_01': {
+    'hash': 36130,
+    'name': 'MRK_Lantern_01',
+    'embedded': {
+      'MRK_Lantern_01_992': {
+        'hash': 992,
+        'name': 'MRK_Lantern_01',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Lantern_Fire': {
+    'hash': 29468,
+    'name': 'MRK_Lantern_Fire',
+    'embedded': {
+      'Fire_29440': {
+        'hash': 29440,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MRK_Lantern_Fire_29466': {
+        'hash': 29466,
+        'name': 'MRK_Lantern_Fire',
+        'savables': {
+          'FireLogic': {
+            'hash': 1509838052,
+            'name': 'FireLogic'
+          },
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Large_Gear_Variant': {
+    'hash': 29874,
+    'name': 'MRK_Large_Gear_Variant',
+    'embedded': {
+      'MRK_Large_Gear_Variant_26800': {
+        'hash': 26800,
+        'name': 'MRK_Large_Gear_Variant',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'Start_Rotating_5010': {
+        'hash': 5010,
+        'name': 'Start_Rotating',
+        'savables': {}
+      },
+      'Stop_Rotating_4822': {
+        'hash': 4822,
+        'name': 'Stop_Rotating',
+        'savables': {}
+      }
+    }
+  },
+  'MRK_Large_Lever': {
+    'hash': 12812,
+    'name': 'MRK_Large_Lever',
+    'embedded': {
+      'MRK_Large_Lever_9436': {
+        'hash': 9436,
+        'name': 'MRK_Large_Lever',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'mrk_large_lever_handle_ROT_2408': {
+        'hash': 2408,
+        'name': 'mrk_large_lever_handle_ROT',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'mrk_large_lever_handle_grip_44324': {
+        'hash': 44324,
+        'name': 'mrk_large_lever_handle_grip',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Liftable_Pipe_Gate': {
+    'hash': 9344,
+    'name': 'MRK_Liftable_Pipe_Gate',
+    'embedded': {
+      'Bottom_Handle_14368': {
+        'hash': 14368,
+        'name': 'Bottom_Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_60880': {
+        'hash': 60880,
+        'name': 'Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_9490': {
+        'hash': 9490,
+        'name': 'Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'MRK_Liftable_Pipe_Gate_47896': {
+        'hash': 47896,
+        'name': 'MRK_Liftable_Pipe_Gate',
+        'savables': {}
+      },
+      'mrk_pipe_gate_door_41532': {
+        'hash': 41532,
+        'name': 'mrk_pipe_gate_door',
+        'savables': {
+          'MovePickup': {
+            'hash': 1874870249,
+            'name': 'MovePickup'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Molten_Core': {
+    'hash': 51764,
+    'name': 'MRK_Molten_Core',
+    'embedded': {
+      'MRK_Molten_Core_21206': {
+        'hash': 21206,
+        'name': 'MRK_Molten_Core',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Pipe_Gate': {
+    'hash': 49320,
+    'name': 'MRK_Pipe_Gate',
+    'embedded': {
+      'MRK_Pipe_Gate_47896': {
+        'hash': 47896,
+        'name': 'MRK_Pipe_Gate',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SlidingDoor': {
+            'hash': 3583462804,
+            'name': 'SlidingDoor'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Puzzle_Core_01': {
+    'hash': 14158,
+    'name': 'MRK_Puzzle_Core_01',
+    'embedded': {
+      'MRK_Puzzle_Core_01_12014': {
+        'hash': 12014,
+        'name': 'MRK_Puzzle_Core_01',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Puzzle_Core_02': {
+    'hash': 28416,
+    'name': 'MRK_Puzzle_Core_02',
+    'embedded': {
+      'MRK_Puzzle_Core_02_12014': {
+        'hash': 12014,
+        'name': 'MRK_Puzzle_Core_02',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Puzzle_Core_Initial_Stand_01_Variant': {
+    'hash': 60550,
+    'name': 'MRK_Puzzle_Core_Initial_Stand_01_Variant',
+    'embedded': {
+      'MRK_Puzzle_Core_Initial_Stand_01_Variant_57012': {
+        'hash': 57012,
+        'name': 'MRK_Puzzle_Core_Initial_Stand_01_Variant',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          },
+          'PlaceItemPuzzleLogic': {
+            'hash': 1001395212,
+            'name': 'PlaceItemPuzzleLogic'
+          }
+        }
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Puzzle_Core_Initial_Stand_02_Variant': {
+    'hash': 30056,
+    'name': 'MRK_Puzzle_Core_Initial_Stand_02_Variant',
+    'embedded': {
+      'MRK_Puzzle_Core_Initial_Stand_02_Variant_57012': {
+        'hash': 57012,
+        'name': 'MRK_Puzzle_Core_Initial_Stand_02_Variant',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          },
+          'PlaceItemPuzzleLogic': {
+            'hash': 1001395212,
+            'name': 'PlaceItemPuzzleLogic'
+          }
+        }
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Puzzle_Core_Stand_01': {
+    'hash': 58540,
+    'name': 'MRK_Puzzle_Core_Stand_01',
+    'embedded': {
+      'MRK_Puzzle_Core_Stand_01_57012': {
+        'hash': 57012,
+        'name': 'MRK_Puzzle_Core_Stand_01',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          },
+          'PlaceItemPuzzleLogic': {
+            'hash': 1001395212,
+            'name': 'PlaceItemPuzzleLogic'
+          }
+        }
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Puzzle_Core_Stand_02': {
+    'hash': 34594,
+    'name': 'MRK_Puzzle_Core_Stand_02',
+    'embedded': {
+      'MRK_Puzzle_Core_Stand_02_57012': {
+        'hash': 57012,
+        'name': 'MRK_Puzzle_Core_Stand_02',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          },
+          'PlaceItemPuzzleLogic': {
+            'hash': 1001395212,
+            'name': 'PlaceItemPuzzleLogic'
+          }
+        }
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Slip_Door': {
+    'hash': 14114,
+    'name': 'MRK_Slip_Door',
+    'embedded': {
+      'Grip_22142': {
+        'hash': 22142,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_22248': {
+        'hash': 22248,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_Point_21894': {
+        'hash': 21894,
+        'name': 'Grip_Point',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_Point_21920': {
+        'hash': 21920,
+        'name': 'Grip_Point',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_Point_22194': {
+        'hash': 22194,
+        'name': 'Grip_Point',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_Point_22228': {
+        'hash': 22228,
+        'name': 'Grip_Point',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_Point_22240': {
+        'hash': 22240,
+        'name': 'Grip_Point',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'MRK_Slip_Door_26828': {
+        'hash': 26828,
+        'name': 'MRK_Slip_Door',
+        'savables': {}
+      },
+      'mrk_slipDoor_gate_26512': {
+        'hash': 26512,
+        'name': 'mrk_slipDoor_gate',
+        'savables': {
+          'MovePickup': {
+            'hash': 1874870249,
+            'name': 'MovePickup'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Small_Lever': {
+    'hash': 1330,
+    'name': 'MRK_Small_Lever',
+    'embedded': {
+      'MRK_Small_Lever_9436': {
+        'hash': 9436,
+        'name': 'MRK_Small_Lever',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'mrk_large_lever_handle_grip_44324': {
+        'hash': 44324,
+        'name': 'mrk_large_lever_handle_grip',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'mrk_small_lever_handle_ROT_29376': {
+        'hash': 29376,
+        'name': 'mrk_small_lever_handle_ROT',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Smelter_Gem_Pedestal_1': {
+    'hash': 33006,
+    'name': 'MRK_Smelter_Gem_Pedestal_1',
+    'embedded': {
+      'MRK_Smelter_Gem_Pedestal_1_27194': {
+        'hash': 27194,
+        'name': 'MRK_Smelter_Gem_Pedestal_1',
+        'savables': {}
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Smelter_Gem_Pedestal_2': {
+    'hash': 56376,
+    'name': 'MRK_Smelter_Gem_Pedestal_2',
+    'embedded': {
+      'MRK_Smelter_Gem_Pedestal_2_27194': {
+        'hash': 27194,
+        'name': 'MRK_Smelter_Gem_Pedestal_2',
+        'savables': {}
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_Smelter_Gem_Pedestal_3': {
+    'hash': 57516,
+    'name': 'MRK_Smelter_Gem_Pedestal_3',
+    'embedded': {
+      'MRK_Smelter_Gem_Pedestal_3_27194': {
+        'hash': 27194,
+        'name': 'MRK_Smelter_Gem_Pedestal_3',
+        'savables': {}
+      },
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      }
+    }
+  },
+  'MRK_TeleporterOut': {
+    'hash': 49418,
+    'name': 'MRK_TeleporterOut',
+    'embedded': {
+      'MRK_Tele_Target_38234': {
+        'hash': 38234,
+        'name': 'MRK_Tele_Target',
+        'savables': {}
+      },
+      'MRK_TeleporterOut_7710': {
+        'hash': 7710,
+        'name': 'MRK_TeleporterOut',
+        'savables': {
+          'LogicVector3Receiver': {
+            'hash': 1228539097,
+            'name': 'LogicVector3Receiver'
+          },
+          'LogicVector3Sender': {
+            'hash': 2026743731,
+            'name': 'LogicVector3Sender'
+          },
+          'PositionProvider': {
+            'hash': 3538443740,
+            'name': 'PositionProvider'
+          },
+          'TeleportationPoint': {
+            'hash': 3146178080,
+            'name': 'TeleportationPoint'
+          }
+        }
+      },
+      'Teleporter_27092': {
+        'hash': 27092,
+        'name': 'Teleporter',
+        'savables': {}
+      }
+    }
+  },
+  'MRK_Wheel_Bridge': {
+    'hash': 61844,
+    'name': 'MRK_Wheel_Bridge',
+    'embedded': {
+      'Crank_Rise_8062': {
+        'hash': 8062,
+        'name': 'Crank_Rise',
+        'savables': {}
+      },
+      'MRK_Wheel_Bridge_43884': {
+        'hash': 43884,
+        'name': 'MRK_Wheel_Bridge',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          },
+          'RotatePickup': {
+            'hash': 2498617949,
+            'name': 'RotatePickup'
+          }
+        }
+      },
+      'mrk_large_handle_01_23224': {
+        'hash': 23224,
+        'name': 'mrk_large_handle_01',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'mrk_large_handle_01_23226': {
+        'hash': 23226,
+        'name': 'mrk_large_handle_01',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'mrk_large_handle_01_23228': {
+        'hash': 23228,
+        'name': 'mrk_large_handle_01',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'mrk_large_handle_01_23230': {
+        'hash': 23230,
+        'name': 'mrk_large_handle_01',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'mrk_large_handle_01_52566': {
+        'hash': 52566,
+        'name': 'mrk_large_handle_01',
+        'savables': {
+          'Crank': {
+            'hash': 1588536425,
+            'name': 'Crank'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'mrk_rotating_platform_ROT_35674': {
+        'hash': 35674,
+        'name': 'mrk_rotating_platform_ROT',
+        'savables': {
+          'WheelGrab': {
+            'hash': 320224849,
+            'name': 'WheelGrab'
+          }
+        }
+      }
+    }
+  },
+  'MRK_activation_lever': {
+    'hash': 35030,
+    'name': 'MRK_activation_lever',
+    'embedded': {
+      'Cost_Definition_20328': {
+        'hash': 20328,
+        'name': 'Cost_Definition',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_22852': {
+        'hash': 22852,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Gacha_Turn_15766': {
+        'hash': 15766,
+        'name': 'Gacha_Turn',
+        'savables': {}
+      },
+      'MRK_activation_lever_34108': {
+        'hash': 34108,
+        'name': 'MRK_activation_lever',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'MRK_ActivationLever': {
+            'hash': 2069630919,
+            'name': 'MRK_ActivationLever'
+          }
+        }
+      },
+      'Stop_Rotating_48244': {
+        'hash': 48244,
+        'name': 'Stop_Rotating',
+        'savables': {}
+      },
+      'Stop_Rotating_48620': {
+        'hash': 48620,
+        'name': 'Stop_Rotating',
+        'savables': {}
+      },
+      'mrk_activation_lever_ROT_8682': {
+        'hash': 8682,
+        'name': 'mrk_activation_lever_ROT',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'MRK_gate_01': {
+    'hash': 3094,
+    'name': 'MRK_gate_01',
+    'embedded': {
+      'MRK_gate_01_42408': {
+        'hash': 42408,
+        'name': 'MRK_gate_01',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SlidingDoor': {
+            'hash': 3583462804,
+            'name': 'SlidingDoor'
+          }
+        }
+      }
+    }
+  },
+  'MRK_gate_01_1.5x_Variant': {
+    'hash': 64136,
+    'name': 'MRK_gate_01_1.5x_Variant',
+    'embedded': {
+      'MRK_gate_01_1.5x_Variant_42408': {
+        'hash': 42408,
+        'name': 'MRK_gate_01_1.5x_Variant',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SlidingDoor': {
+            'hash': 3583462804,
+            'name': 'SlidingDoor'
+          }
+        }
+      }
+    }
+  },
+  'MRK_gate_02': {
+    'hash': 54328,
+    'name': 'MRK_gate_02',
+    'embedded': {
+      'MRK_gate_02_42408': {
+        'hash': 42408,
+        'name': 'MRK_gate_02',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SlidingDoor': {
+            'hash': 3583462804,
+            'name': 'SlidingDoor'
+          }
+        }
+      }
+    }
+  },
+  'MRK_heartReceptacle_01': {
+    'hash': 9566,
+    'name': 'MRK_heartReceptacle_01',
+    'embedded': {
+      'Hand_Touch_13548': {
+        'hash': 13548,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'MRK_heartReceptacle_01_7518': {
+        'hash': 7518,
+        'name': 'MRK_heartReceptacle_01',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'OneTimeUpgradeInteraction': {
+            'hash': 3230087383,
+            'name': 'OneTimeUpgradeInteraction'
+          }
+        }
+      }
+    }
+  },
+  'Mail_Deposit_Box': {
+    'hash': 64204,
+    'name': 'Mail_Deposit_Box',
+    'embedded': {
+      'Cost_Dock_9564': {
+        'hash': 9564,
+        'name': 'Cost_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_23190': {
+        'hash': 23190,
+        'name': 'Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Mail_Deposit_Box_64110': {
+        'hash': 64110,
+        'name': 'Mail_Deposit_Box',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Scroller_64946': {
+        'hash': 64946,
+        'name': 'Scroller',
+        'savables': {}
+      },
+      'Send_Dock_Area_33168': {
+        'hash': 33168,
+        'name': 'Send_Dock_Area',
+        'savables': {}
+      },
+      'Sending_Dock_1_9562': {
+        'hash': 9562,
+        'name': 'Sending_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Sending_Dock_2_54962': {
+        'hash': 54962,
+        'name': 'Sending_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Sending_Dock_3_9442': {
+        'hash': 9442,
+        'name': 'Sending_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'mail_depositBox_swivel_51358': {
+        'hash': 51358,
+        'name': 'mail_depositBox_swivel',
+        'savables': {}
+      },
+      'scroller_throttle_handMetal_LOD0_31026': {
+        'hash': 31026,
+        'name': 'scroller_throttle_handMetal_LOD0',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Main_Menu_Controller': {
+    'hash': 58810,
+    'name': 'Main_Menu_Controller',
+    'embedded': {}
+  },
+  'Map_Board': {
+    'hash': 60974,
+    'name': 'Map_Board',
+    'embedded': {
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'Map_Board_63822': {
+        'hash': 63822,
+        'name': 'Map_Board',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          },
+          'MapBoard': {
+            'hash': 2443660852,
+            'name': 'MapBoard'
+          }
+        }
+      }
+    }
+  },
+  'Material_Box': {
+    'hash': 46376,
+    'name': 'Material_Box',
+    'embedded': {
+      'Loot_Spawner_46196': {
+        'hash': 46196,
+        'name': 'Loot_Spawner',
+        'savables': {}
+      },
+      'Material_Box_46360': {
+        'hash': 46360,
+        'name': 'Material_Box',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Pieces_Spawner_23704': {
+        'hash': 23704,
+        'name': 'Pieces_Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Material_Box_Pieces': {
+    'hash': 42982,
+    'name': 'Material_Box_Pieces',
+    'embedded': {
+      'Material_Box_Pieces_43372': {
+        'hash': 43372,
+        'name': 'Material_Box_Pieces',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Metal_Bow': {
+    'hash': 25100,
+    'name': 'Metal_Bow',
+    'embedded': {
+      'Arrow_Dock_25108': {
+        'hash': 25108,
+        'name': 'Arrow_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Metal_Bow_25094': {
+        'hash': 25094,
+        'name': 'Metal_Bow',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Bow_Blade_10188': {
+        'hash': 10188,
+        'name': 'Slot_Bow_Blade',
+        'savables': {}
+      },
+      'Slot_Bow_Blade_252': {
+        'hash': 252,
+        'name': 'Slot_Bow_Blade',
+        'savables': {}
+      },
+      'Slot_Deco_61122': {
+        'hash': 61122,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_65334': {
+        'hash': 65334,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'String_25106': {
+        'hash': 25106,
+        'name': 'String',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Metal_Hammer_Head': {
+    'hash': 22876,
+    'name': 'Metal_Hammer_Head',
+    'embedded': {
+      'Heat_Point_Collection_1368': {
+        'hash': 1368,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_52192': {
+        'hash': 52192,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      },
+      'Metal_Hammer_Head_42978': {
+        'hash': 42978,
+        'name': 'Metal_Hammer_Head',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Deco_37872': {
+        'hash': 37872,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_48318': {
+        'hash': 48318,
+        'name': 'Slot_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Metal_Hebios_Katana_Blade': {
+    'hash': 17174,
+    'name': 'Metal_Hebios_Katana_Blade',
+    'embedded': {
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'Metal_Hebios_Katana_Blade_57166': {
+        'hash': 57166,
+        'name': 'Metal_Hebios_Katana_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'katana_blade_part_full_30124': {
+        'hash': 30124,
+        'name': 'katana_blade_part_full',
+        'savables': {}
+      }
+    }
+  },
+  'Metal_Hebios_Naginata_Blade': {
+    'hash': 15124,
+    'name': 'Metal_Hebios_Naginata_Blade',
+    'embedded': {
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'Metal_Hebios_Naginata_Blade_57606': {
+        'hash': 57606,
+        'name': 'Metal_Hebios_Naginata_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'naginata_blade_LOD0_56264': {
+        'hash': 56264,
+        'name': 'naginata_blade_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Metal_Hebios_Sai_Blade': {
+    'hash': 53124,
+    'name': 'Metal_Hebios_Sai_Blade',
+    'embedded': {
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'Metal_Hebios_Sai_Blade_57606': {
+        'hash': 57606,
+        'name': 'Metal_Hebios_Sai_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'sai_blade_LOD0_11144': {
+        'hash': 11144,
+        'name': 'sai_blade_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Metal_Hebios_Wakizashi_Blade': {
+    'hash': 48902,
+    'name': 'Metal_Hebios_Wakizashi_Blade',
+    'embedded': {
+      'Insert_Straight_Short_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_Short_SwordType',
+        'savables': {}
+      },
+      'Metal_Hebios_Wakizashi_Blade_57606': {
+        'hash': 57606,
+        'name': 'Metal_Hebios_Wakizashi_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'wakizashi_blade_26702': {
+        'hash': 26702,
+        'name': 'wakizashi_blade',
+        'savables': {}
+      }
+    }
+  },
+  'Metal_Tap': {
+    'hash': 17334,
+    'name': 'Metal_Tap',
+    'embedded': {
+      'Metal_Tap_20796': {
+        'hash': 20796,
+        'name': 'Metal_Tap',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Metal_Wall_Hook': {
+    'hash': 61180,
+    'name': 'Metal_Wall_Hook',
+    'embedded': {}
+  },
+  'Mining_Base_Generator': {
+    'hash': 6714,
+    'name': 'Mining_Base_Generator',
+    'embedded': {
+      'Mining_Base_Generator_6374': {
+        'hash': 6374,
+        'name': 'Mining_Base_Generator',
+        'savables': {}
+      }
+    }
+  },
+  'Mining_Path': {
+    'hash': 30950,
+    'name': 'Mining_Path',
+    'embedded': {
+      'Mining_Path_30946': {
+        'hash': 30946,
+        'name': 'Mining_Path',
+        'savables': {
+          'PopulationPath': {
+            'hash': 7704646,
+            'name': 'PopulationPath'
+          }
+        }
+      }
+    }
+  },
+  'Modular_Backpack': {
+    'hash': 12060,
+    'name': 'Modular_Backpack',
+    'embedded': {}
+  },
+  'Modular_Hook': {
+    'hash': 60188,
+    'name': 'Modular_Hook',
+    'embedded': {}
+  },
+  'Modular_Sack': {
+    'hash': 8344,
+    'name': 'Modular_Sack',
+    'embedded': {}
+  },
+  'Mother_Fern': {
+    'hash': 65004,
+    'name': 'Mother_Fern',
+    'embedded': {
+      'Death_Fern_AI_29794': {
+        'hash': 29794,
+        'name': 'Death_Fern_AI',
+        'savables': {}
+      },
+      'Emit_Gas_Spawner_16984': {
+        'hash': 16984,
+        'name': 'Emit_Gas_Spawner',
+        'savables': {}
+      },
+      'Mesh_15308': {
+        'hash': 15308,
+        'name': 'Mesh',
+        'savables': {}
+      },
+      'Mother_Fern_37626': {
+        'hash': 37626,
+        'name': 'Mother_Fern',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Seed_Spray_1172': {
+        'hash': 1172,
+        'name': 'Seed_Spray',
+        'savables': {}
+      }
+    }
+  },
+  'Mother_Fern_Seed_Spray': {
+    'hash': 26710,
+    'name': 'Mother_Fern_Seed_Spray',
+    'embedded': {
+      'Mother_Fern_Seed_Spray_44772': {
+        'hash': 44772,
+        'name': 'Mother_Fern_Seed_Spray',
+        'savables': {}
+      }
+    }
+  },
+  'Mould': {
+    'hash': 14826,
+    'name': 'Mould',
+    'embedded': {
+      'Mould_14710': {
+        'hash': 14710,
+        'name': 'Mould',
+        'savables': {
+          'Mould': {
+            'hash': 391977879,
+            'name': 'Mould'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Mould_Press_Hebios': {
+    'hash': 2594,
+    'name': 'Mould_Press_Hebios',
+    'embedded': {
+      'Input_36080': {
+        'hash': 36080,
+        'name': 'Input',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Lever_Physics_45996': {
+        'hash': 45996,
+        'name': 'Lever_Physics',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Mould_Press_Hebios_65312': {
+        'hash': 65312,
+        'name': 'Mould_Press_Hebios',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Output_52720': {
+        'hash': 52720,
+        'name': 'Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Mould_Press_Standard': {
+    'hash': 13362,
+    'name': 'Mould_Press_Standard',
+    'embedded': {
+      'Input_36080': {
+        'hash': 36080,
+        'name': 'Input',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Lever_Physics_45996': {
+        'hash': 45996,
+        'name': 'Lever_Physics',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Mould_Press_Standard_65312': {
+        'hash': 65312,
+        'name': 'Mould_Press_Standard',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Output_52720': {
+        'hash': 52720,
+        'name': 'Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Mould_Rack': {
+    'hash': 4070,
+    'name': 'Mould_Rack',
+    'embedded': {
+      'Dock_57418': {
+        'hash': 57418,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57450': {
+        'hash': 57450,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57456': {
+        'hash': 57456,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57470': {
+        'hash': 57470,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57504': {
+        'hash': 57504,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57528': {
+        'hash': 57528,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57550': {
+        'hash': 57550,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_57556': {
+        'hash': 57556,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Mould_Rack_498': {
+        'hash': 498,
+        'name': 'Mould_Rack',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Rope_Grab_57800': {
+        'hash': 57800,
+        'name': 'Rope_Grab',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'RopeGrab': {
+            'hash': 237360636,
+            'name': 'RopeGrab'
+          }
+        }
+      },
+      'Rope_Length_57794': {
+        'hash': 57794,
+        'name': 'Rope_Length',
+        'savables': {}
+      }
+    }
+  },
+  'Mould_Restriction_Zone': {
+    'hash': 4900,
+    'name': 'Mould_Restriction_Zone',
+    'embedded': {
+      'Mould_Restriction_Zone_2804': {
+        'hash': 2804,
+        'name': 'Mould_Restriction_Zone',
+        'savables': {
+          'MouldRestrictor': {
+            'hash': 1571096900,
+            'name': 'MouldRestrictor'
+          }
+        }
+      }
+    }
+  },
+  'MushroomBrown_Full_Burnt': {
+    'hash': 47126,
+    'name': 'MushroomBrown_Full_Burnt',
+    'embedded': {
+      'Cooking_35920': {
+        'hash': 35920,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomBrown_Full_Burnt_36010': {
+        'hash': 36010,
+        'name': 'MushroomBrown_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomBrown_Full_Cooked': {
+    'hash': 46510,
+    'name': 'MushroomBrown_Full_Cooked',
+    'embedded': {
+      'Cooking_32900': {
+        'hash': 32900,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomBrown_Full_Cooked_32990': {
+        'hash': 32990,
+        'name': 'MushroomBrown_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomBrown_Full_Ripe': {
+    'hash': 61666,
+    'name': 'MushroomBrown_Full_Ripe',
+    'embedded': {
+      'Cooking_30802': {
+        'hash': 30802,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomBrown_Full_Ripe_30892': {
+        'hash': 30892,
+        'name': 'MushroomBrown_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomBrown_Half_Burnt': {
+    'hash': 53372,
+    'name': 'MushroomBrown_Half_Burnt',
+    'embedded': {
+      'Cooking_28740': {
+        'hash': 28740,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomBrown_Half_Burnt_28794': {
+        'hash': 28794,
+        'name': 'MushroomBrown_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomBrown_Half_Cooked': {
+    'hash': 50916,
+    'name': 'MushroomBrown_Half_Cooked',
+    'embedded': {
+      'Cooking_26756': {
+        'hash': 26756,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomBrown_Half_Cooked_26810': {
+        'hash': 26810,
+        'name': 'MushroomBrown_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomBrown_Half_Ripe': {
+    'hash': 48460,
+    'name': 'MushroomBrown_Half_Ripe',
+    'embedded': {
+      'Cooking_24846': {
+        'hash': 24846,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomBrown_Half_Ripe_24900': {
+        'hash': 24900,
+        'name': 'MushroomBrown_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveLarge_Half_Burnt': {
+    'hash': 60330,
+    'name': 'MushroomCaveLarge_Half_Burnt',
+    'embedded': {
+      'Cooking_60736': {
+        'hash': 60736,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveLarge_Half_Burnt_61496': {
+        'hash': 61496,
+        'name': 'MushroomCaveLarge_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveLarge_Half_Cooked': {
+    'hash': 9414,
+    'name': 'MushroomCaveLarge_Half_Cooked',
+    'embedded': {
+      'Cooking_55004': {
+        'hash': 55004,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveLarge_Half_Cooked_55764': {
+        'hash': 55764,
+        'name': 'MushroomCaveLarge_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveLarge_Half_Ripe': {
+    'hash': 54182,
+    'name': 'MushroomCaveLarge_Half_Ripe',
+    'embedded': {
+      'Cooking_49572': {
+        'hash': 49572,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveLarge_Half_Ripe_50332': {
+        'hash': 50332,
+        'name': 'MushroomCaveLarge_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveSmall_Full_Burnt': {
+    'hash': 29148,
+    'name': 'MushroomCaveSmall_Full_Burnt',
+    'embedded': {
+      'Cooking_27474': {
+        'hash': 27474,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveSmall_Full_Burnt_28332': {
+        'hash': 28332,
+        'name': 'MushroomCaveSmall_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveSmall_Full_Cooked': {
+    'hash': 40066,
+    'name': 'MushroomCaveSmall_Full_Cooked',
+    'embedded': {
+      'Cooking_34902': {
+        'hash': 34902,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveSmall_Full_Cooked_35760': {
+        'hash': 35760,
+        'name': 'MushroomCaveSmall_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveSmall_Full_Ripe': {
+    'hash': 58270,
+    'name': 'MushroomCaveSmall_Full_Ripe',
+    'embedded': {
+      'Cooking_28844': {
+        'hash': 28844,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveSmall_Full_Ripe_29702': {
+        'hash': 29702,
+        'name': 'MushroomCaveSmall_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveSmall_Half_Burnt': {
+    'hash': 47142,
+    'name': 'MushroomCaveSmall_Half_Burnt',
+    'embedded': {
+      'Cooking_23588': {
+        'hash': 23588,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveSmall_Half_Burnt_23644': {
+        'hash': 23644,
+        'name': 'MushroomCaveSmall_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveSmall_Half_Cooked': {
+    'hash': 44488,
+    'name': 'MushroomCaveSmall_Half_Cooked',
+    'embedded': {
+      'Cooking_21474': {
+        'hash': 21474,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveSmall_Half_Cooked_21530': {
+        'hash': 21530,
+        'name': 'MushroomCaveSmall_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomCaveSmall_Half_Ripe': {
+    'hash': 41834,
+    'name': 'MushroomCaveSmall_Half_Ripe',
+    'embedded': {
+      'Cooking_19434': {
+        'hash': 19434,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomCaveSmall_Half_Ripe_19490': {
+        'hash': 19490,
+        'name': 'MushroomCaveSmall_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomGlowing_Full_Burnt': {
+    'hash': 43856,
+    'name': 'MushroomGlowing_Full_Burnt',
+    'embedded': {
+      'Cooking_13584': {
+        'hash': 13584,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomGlowing_Full_Burnt_41450': {
+        'hash': 41450,
+        'name': 'MushroomGlowing_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomGlowing_Full_Cooked': {
+    'hash': 41428,
+    'name': 'MushroomGlowing_Full_Cooked',
+    'embedded': {
+      'Cooking_6452': {
+        'hash': 6452,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomGlowing_Full_Cooked_14334': {
+        'hash': 14334,
+        'name': 'MushroomGlowing_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomGlowing_Full_Ripe': {
+    'hash': 38966,
+    'name': 'MushroomGlowing_Full_Ripe',
+    'embedded': {
+      'Cooking_1062': {
+        'hash': 1062,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomGlowing_Full_Ripe_33808': {
+        'hash': 33808,
+        'name': 'MushroomGlowing_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomGlowing_Half_Burnt': {
+    'hash': 36504,
+    'name': 'MushroomGlowing_Half_Burnt',
+    'embedded': {
+      'Cooking_61912': {
+        'hash': 61912,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomGlowing_Half_Burnt_37030': {
+        'hash': 37030,
+        'name': 'MushroomGlowing_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomGlowing_Half_Cooked': {
+    'hash': 34042,
+    'name': 'MushroomGlowing_Half_Cooked',
+    'embedded': {
+      'Cooking_60048': {
+        'hash': 60048,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomGlowing_Half_Cooked_14126': {
+        'hash': 14126,
+        'name': 'MushroomGlowing_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomGlowing_Half_Ripe': {
+    'hash': 31580,
+    'name': 'MushroomGlowing_Half_Ripe',
+    'embedded': {
+      'Cooking_58186': {
+        'hash': 58186,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomGlowing_Half_Ripe_59620': {
+        'hash': 59620,
+        'name': 'MushroomGlowing_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomRed_Full_Burnt': {
+    'hash': 46660,
+    'name': 'MushroomRed_Full_Burnt',
+    'embedded': {
+      'Cooking_15932': {
+        'hash': 15932,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomRed_Full_Burnt_16724': {
+        'hash': 16724,
+        'name': 'MushroomRed_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomRed_Full_Cooked': {
+    'hash': 46888,
+    'name': 'MushroomRed_Full_Cooked',
+    'embedded': {
+      'Cooking_29424': {
+        'hash': 29424,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomRed_Full_Cooked_30216': {
+        'hash': 30216,
+        'name': 'MushroomRed_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomRed_Full_Ripe': {
+    'hash': 61658,
+    'name': 'MushroomRed_Full_Ripe',
+    'embedded': {
+      'Cooking_23868': {
+        'hash': 23868,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomRed_Full_Ripe_24660': {
+        'hash': 24660,
+        'name': 'MushroomRed_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomRed_Half_Burnt': {
+    'hash': 43272,
+    'name': 'MushroomRed_Half_Burnt',
+    'embedded': {
+      'Cooking_19050': {
+        'hash': 19050,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomRed_Half_Burnt_19104': {
+        'hash': 19104,
+        'name': 'MushroomRed_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomRed_Half_Cooked': {
+    'hash': 40816,
+    'name': 'MushroomRed_Half_Cooked',
+    'embedded': {
+      'Cooking_17118': {
+        'hash': 17118,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomRed_Half_Cooked_17172': {
+        'hash': 17172,
+        'name': 'MushroomRed_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'MushroomRed_Half_Ripe': {
+    'hash': 38360,
+    'name': 'MushroomRed_Half_Ripe',
+    'embedded': {
+      'Cooking_15260': {
+        'hash': 15260,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'MushroomRed_Half_Ripe_15314': {
+        'hash': 15314,
+        'name': 'MushroomRed_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Mushroom_Fairy_Circle_Puzzle': {
+    'hash': 46706,
+    'name': 'Mushroom_Fairy_Circle_Puzzle',
+    'embedded': {
+      'Mushroom_Fairy_Circle_Puzzle_28402': {
+        'hash': 28402,
+        'name': 'Mushroom_Fairy_Circle_Puzzle',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'SpawnInCircle': {
+            'hash': 1714180166,
+            'name': 'SpawnInCircle'
+          }
+        }
+      }
+    }
+  },
+  'Mushroom_Fairy_Circle_Puzzle_OLD': {
+    'hash': 44688,
+    'name': 'Mushroom_Fairy_Circle_Puzzle_OLD',
+    'embedded': {}
+  },
+  'Mushroom_Fairy_Circle_Puzzle_Teleport': {
+    'hash': 28040,
+    'name': 'Mushroom_Fairy_Circle_Puzzle_Teleport',
+    'embedded': {
+      'Mushroom_Fairy_Circle_Puzzle_Teleport_8726': {
+        'hash': 8726,
+        'name': 'Mushroom_Fairy_Circle_Puzzle_Teleport',
+        'savables': {
+          'LogicVector3Receiver': {
+            'hash': 1228539097,
+            'name': 'LogicVector3Receiver'
+          },
+          'LogicVector3Sender': {
+            'hash': 2026743731,
+            'name': 'LogicVector3Sender'
+          },
+          'PositionProvider': {
+            'hash': 3538443740,
+            'name': 'PositionProvider'
+          },
+          'SpawnInCircle': {
+            'hash': 1714180166,
+            'name': 'SpawnInCircle'
+          },
+          'TeleportationPoint': {
+            'hash': 3146178080,
+            'name': 'TeleportationPoint'
+          }
+        }
+      }
+    }
+  },
+  'Mushroom_Mix_Recipe_Burnt_Stew': {
+    'hash': 27398,
+    'name': 'Mushroom_Mix_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Mix_Recipe_Cooked_Stew': {
+    'hash': 27376,
+    'name': 'Mushroom_Mix_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Mix_Recipe_Raw_Stew': {
+    'hash': 14914,
+    'name': 'Mushroom_Mix_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Poultry_Recipe_Burnt_Stew': {
+    'hash': 54614,
+    'name': 'Mushroom_Poultry_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Poultry_Recipe_Cooked_Stew': {
+    'hash': 55358,
+    'name': 'Mushroom_Poultry_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Poultry_Recipe_Raw_Stew': {
+    'hash': 55978,
+    'name': 'Mushroom_Poultry_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Recipe_Burnt_Stew': {
+    'hash': 30560,
+    'name': 'Mushroom_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Recipe_Cooked_Stew': {
+    'hash': 31606,
+    'name': 'Mushroom_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Mushroom_Recipe_Raw_Stew': {
+    'hash': 32650,
+    'name': 'Mushroom_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Mythril_Boulder': {
+    'hash': 27368,
+    'name': 'Mythril_Boulder',
+    'embedded': {
+      'Mythril_Boulder_29328': {
+        'hash': 29328,
+        'name': 'Mythril_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_18860': {
+        'hash': 18860,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Mythril_Boulder_Parts': {
+    'hash': 43522,
+    'name': 'Mythril_Boulder_Parts',
+    'embedded': {
+      'Mythril_Boulder_Parts_59770': {
+        'hash': 59770,
+        'name': 'Mythril_Boulder_Parts',
+        'savables': {}
+      },
+      'Mythril_Boulder_part_01_59808': {
+        'hash': 59808,
+        'name': 'Mythril_Boulder_part_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Mythril_Boulder_part_02_59820': {
+        'hash': 59820,
+        'name': 'Mythril_Boulder_part_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Mythril_Boulder_part_03_59816': {
+        'hash': 59816,
+        'name': 'Mythril_Boulder_part_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Mythril_Boulder_part_04_59804': {
+        'hash': 59804,
+        'name': 'Mythril_Boulder_part_04',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Mythril_Boulder_part_05_59812': {
+        'hash': 59812,
+        'name': 'Mythril_Boulder_part_05',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Mythril_Ingot': {
+    'hash': 24774,
+    'name': 'Mythril_Ingot',
+    'embedded': {
+      'Heat_Point_Collection_13294': {
+        'hash': 13294,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Mythril_Ingot_24662': {
+        'hash': 24662,
+        'name': 'Mythril_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Mythril_Ore': {
+    'hash': 11702,
+    'name': 'Mythril_Ore',
+    'embedded': {
+      'Mythril_Ore_15610': {
+        'hash': 15610,
+        'name': 'Mythril_Ore',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Naginata': {
+    'hash': 41052,
+    'name': 'Naginata',
+    'embedded': {
+      'Naginata_36330': {
+        'hash': 36330,
+        'name': 'Naginata',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Enchantable': {
+            'hash': 4134534481,
+            'name': 'Enchantable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Name_Proxy': {
+    'hash': 15340,
+    'name': 'Name_Proxy',
+    'embedded': {}
+  },
+  'Nand': {
+    'hash': 42426,
+    'name': 'Nand',
+    'embedded': {}
+  },
+  'Navigation_wheel': {
+    'hash': 20416,
+    'name': 'Navigation_wheel',
+    'embedded': {
+      'Grip_(1)_54050': {
+        'hash': 54050,
+        'name': 'Grip_(1)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(2)_54614': {
+        'hash': 54614,
+        'name': 'Grip_(2)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(3)_56370': {
+        'hash': 56370,
+        'name': 'Grip_(3)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(4)_53470': {
+        'hash': 53470,
+        'name': 'Grip_(4)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_56728': {
+        'hash': 56728,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Navigation_wheel_16790': {
+        'hash': 16790,
+        'name': 'Navigation_wheel',
+        'savables': {}
+      }
+    }
+  },
+  'New_Tree_Grower': {
+    'hash': 62444,
+    'name': 'New_Tree_Grower',
+    'embedded': {
+      'New_Tree_Grower_52858': {
+        'hash': 52858,
+        'name': 'New_Tree_Grower',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Non_Recipe_Burnt_Stew': {
+    'hash': 48634,
+    'name': 'Non_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Non_Recipe_Cooked_Stew': {
+    'hash': 49314,
+    'name': 'Non_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Non_Recipe_Raw_Stew': {
+    'hash': 49962,
+    'name': 'Non_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Nor': {
+    'hash': 42420,
+    'name': 'Nor',
+    'embedded': {}
+  },
+  'Not': {
+    'hash': 42414,
+    'name': 'Not',
+    'embedded': {}
+  },
+  'Oak_Tree_Growth': {
+    'hash': 48238,
+    'name': 'Oak_Tree_Growth',
+    'embedded': {
+      'Oak_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Oak_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Oak_Tree_Seed': {
+    'hash': 17302,
+    'name': 'Oak_Tree_Seed',
+    'embedded': {
+      'Oak_Tree_Seed_35258': {
+        'hash': 35258,
+        'name': 'Oak_Tree_Seed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Oak_Tree_Stage_1': {
+    'hash': 17412,
+    'name': 'Oak_Tree_Stage_1',
+    'embedded': {
+      'Oak_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Oak_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Obstacle_Path': {
+    'hash': 62838,
+    'name': 'Obstacle_Path',
+    'embedded': {
+      'Obstacle_Path_30946': {
+        'hash': 30946,
+        'name': 'Obstacle_Path',
+        'savables': {
+          'PopulationPath': {
+            'hash': 7704646,
+            'name': 'PopulationPath'
+          }
+        }
+      }
+    }
+  },
+  'One_Time_Upgrade_Station_Health': {
+    'hash': 46992,
+    'name': 'One_Time_Upgrade_Station_Health',
+    'embedded': {
+      'One_Time_Upgrade_Station_Health_46540': {
+        'hash': 46540,
+        'name': 'One_Time_Upgrade_Station_Health',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'OneTimeUpgradeInteraction': {
+            'hash': 3230087383,
+            'name': 'OneTimeUpgradeInteraction'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Full_Burnt': {
+    'hash': 48718,
+    'name': 'Onion_Full_Burnt',
+    'embedded': {
+      'Cooking_61106': {
+        'hash': 61106,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Full_Burnt_48300': {
+        'hash': 48300,
+        'name': 'Onion_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Full_Cooked': {
+    'hash': 48214,
+    'name': 'Onion_Full_Cooked',
+    'embedded': {
+      'Cooking_60678': {
+        'hash': 60678,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Full_Cooked_47812': {
+        'hash': 47812,
+        'name': 'Onion_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Full_Ripe': {
+    'hash': 47730,
+    'name': 'Onion_Full_Ripe',
+    'embedded': {
+      'Cooking_58282': {
+        'hash': 58282,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Leaves_Parent_20548': {
+        'hash': 20548,
+        'name': 'Leaves_Parent',
+        'savables': {}
+      },
+      'Onion_Full_Ripe_44704': {
+        'hash': 44704,
+        'name': 'Onion_Full_Ripe',
+        'savables': {
+          'BuildupPickup': {
+            'hash': 3373651539,
+            'name': 'BuildupPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Roots_Parent_17652': {
+        'hash': 17652,
+        'name': 'Roots_Parent',
+        'savables': {}
+      }
+    }
+  },
+  'Onion_Full_Unripe': {
+    'hash': 43966,
+    'name': 'Onion_Full_Unripe',
+    'embedded': {
+      'Cooking_57758': {
+        'hash': 57758,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Full_Unripe_43436': {
+        'hash': 43436,
+        'name': 'Onion_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Half_Burnt': {
+    'hash': 59314,
+    'name': 'Onion_Half_Burnt',
+    'embedded': {
+      'Cooking_33410': {
+        'hash': 33410,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Half_Burnt_58976': {
+        'hash': 58976,
+        'name': 'Onion_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Half_Cooked': {
+    'hash': 58910,
+    'name': 'Onion_Half_Cooked',
+    'embedded': {
+      'Cooking_33064': {
+        'hash': 33064,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Half_Cooked_58572': {
+        'hash': 58572,
+        'name': 'Onion_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Half_Ripe': {
+    'hash': 58506,
+    'name': 'Onion_Half_Ripe',
+    'embedded': {
+      'Cooking_32718': {
+        'hash': 32718,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Half_Ripe_58168': {
+        'hash': 58168,
+        'name': 'Onion_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Half_Unripe': {
+    'hash': 58102,
+    'name': 'Onion_Half_Unripe',
+    'embedded': {
+      'Cooking_32372': {
+        'hash': 32372,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Onion_Half_Unripe_57764': {
+        'hash': 57764,
+        'name': 'Onion_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Leaves': {
+    'hash': 29078,
+    'name': 'Onion_Leaves',
+    'embedded': {
+      'Onion_Leaves_31538': {
+        'hash': 31538,
+        'name': 'Onion_Leaves',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'PullPickup_51602': {
+        'hash': 51602,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Onion_Roots': {
+    'hash': 32068,
+    'name': 'Onion_Roots',
+    'embedded': {
+      'Onion_Roots_47660': {
+        'hash': 47660,
+        'name': 'Onion_Roots',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'PullPickup_32872': {
+        'hash': 32872,
+        'name': 'PullPickup',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Or': {
+    'hash': 42416,
+    'name': 'Or',
+    'embedded': {}
+  },
+  'Orchi_Ingot': {
+    'hash': 16464,
+    'name': 'Orchi_Ingot',
+    'embedded': {
+      'Heat_Point_Collection_13422': {
+        'hash': 13422,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Orchi_Ingot_32738': {
+        'hash': 32738,
+        'name': 'Orchi_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Ore_Bag': {
+    'hash': 64560,
+    'name': 'Ore_Bag',
+    'embedded': {
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Dock_BM_63062': {
+        'hash': 63062,
+        'name': 'Dock_BM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_L_63242': {
+        'hash': 63242,
+        'name': 'Dock_L',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_R_63236': {
+        'hash': 63236,
+        'name': 'Dock_R',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TM_63222': {
+        'hash': 63222,
+        'name': 'Dock_TM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Ore_Bag_43012': {
+        'hash': 43012,
+        'name': 'Ore_Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Bag_Attach_30776': {
+        'hash': 30776,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_55164': {
+        'hash': 55164,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_62396': {
+        'hash': 62396,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Tool_Attachment_36292': {
+        'hash': 36292,
+        'name': 'Slot_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'Slot_Bag_Tool_Attachment_36386': {
+        'hash': 36386,
+        'name': 'Slot_Bag_Tool_Attachment',
+        'savables': {}
+      },
+      'ore_bag_frame_01_44248': {
+        'hash': 44248,
+        'name': 'ore_bag_frame_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_frame_02_44244': {
+        'hash': 44244,
+        'name': 'ore_bag_frame_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_frame_03_44312': {
+        'hash': 44312,
+        'name': 'ore_bag_frame_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_frame_04_44308': {
+        'hash': 44308,
+        'name': 'ore_bag_frame_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_rim_bottom_44264': {
+        'hash': 44264,
+        'name': 'ore_bag_rim_bottom',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_rim_top_44288': {
+        'hash': 44288,
+        'name': 'ore_bag_rim_top',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_sack_44268': {
+        'hash': 44268,
+        'name': 'ore_bag_sack',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_01_44328': {
+        'hash': 44328,
+        'name': 'ore_bag_stick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_02_44296': {
+        'hash': 44296,
+        'name': 'ore_bag_stick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_03_44284': {
+        'hash': 44284,
+        'name': 'ore_bag_stick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_04_44228': {
+        'hash': 44228,
+        'name': 'ore_bag_stick_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_05_44224': {
+        'hash': 44224,
+        'name': 'ore_bag_stick_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_06_44304': {
+        'hash': 44304,
+        'name': 'ore_bag_stick_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_07_44300': {
+        'hash': 44300,
+        'name': 'ore_bag_stick_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_08_44240': {
+        'hash': 44240,
+        'name': 'ore_bag_stick_08',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_09_44236': {
+        'hash': 44236,
+        'name': 'ore_bag_stick_09',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_10_44324': {
+        'hash': 44324,
+        'name': 'ore_bag_stick_10',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_11_44320': {
+        'hash': 44320,
+        'name': 'ore_bag_stick_11',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_12_44280': {
+        'hash': 44280,
+        'name': 'ore_bag_stick_12',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_stick_13_44232': {
+        'hash': 44232,
+        'name': 'ore_bag_stick_13',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_01_44316': {
+        'hash': 44316,
+        'name': 'ore_bag_strawBind_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_02_44260': {
+        'hash': 44260,
+        'name': 'ore_bag_strawBind_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_03_44276': {
+        'hash': 44276,
+        'name': 'ore_bag_strawBind_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_04_44272': {
+        'hash': 44272,
+        'name': 'ore_bag_strawBind_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_05_44256': {
+        'hash': 44256,
+        'name': 'ore_bag_strawBind_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_06_44252': {
+        'hash': 44252,
+        'name': 'ore_bag_strawBind_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_strawBind_07_44292': {
+        'hash': 44292,
+        'name': 'ore_bag_strawBind_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_handle_body_14308': {
+        'hash': 14308,
+        'name': 'standard_bag_handle_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_bag_handle_wraps_14304': {
+        'hash': 14304,
+        'name': 'standard_bag_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Ore_Side_Pouch_Attachment': {
+    'hash': 61020,
+    'name': 'Ore_Side_Pouch_Attachment',
+    'embedded': {
+      'Dock_45700': {
+        'hash': 45700,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Insert_Bag_Attach_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Attach',
+        'savables': {}
+      },
+      'Ore_Side_Pouch_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Ore_Side_Pouch_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Storage_53834': {
+        'hash': 53834,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'ore_bag_attachment_cloth_01_30702': {
+        'hash': 30702,
+        'name': 'ore_bag_attachment_cloth_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_cloth_cover_43718': {
+        'hash': 43718,
+        'name': 'ore_bag_attachment_cloth_cover',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_knot_01_30682': {
+        'hash': 30682,
+        'name': 'ore_bag_attachment_knot_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_knot_02_30678': {
+        'hash': 30678,
+        'name': 'ore_bag_attachment_knot_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_knot_03_30674': {
+        'hash': 30674,
+        'name': 'ore_bag_attachment_knot_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_knot_04_30670': {
+        'hash': 30670,
+        'name': 'ore_bag_attachment_knot_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_stick_01_30698': {
+        'hash': 30698,
+        'name': 'ore_bag_attachment_stick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_stick_02_30694': {
+        'hash': 30694,
+        'name': 'ore_bag_attachment_stick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_stick_03_30690': {
+        'hash': 30690,
+        'name': 'ore_bag_attachment_stick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_stick_04_30686': {
+        'hash': 30686,
+        'name': 'ore_bag_attachment_stick_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_stick_05_30658': {
+        'hash': 30658,
+        'name': 'ore_bag_attachment_stick_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'ore_bag_attachment_stick_06_30654': {
+        'hash': 30654,
+        'name': 'ore_bag_attachment_stick_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Ore_Storage': {
+    'hash': 65420,
+    'name': 'Ore_Storage',
+    'embedded': {
+      'Filter_Dock_57214': {
+        'hash': 57214,
+        'name': 'Filter_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Interaction_Point_59032': {
+        'hash': 59032,
+        'name': 'Interaction_Point',
+        'savables': {}
+      },
+      'Internal_Dock_59328': {
+        'hash': 59328,
+        'name': 'Internal_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Ore_Storage_65062': {
+        'hash': 65062,
+        'name': 'Ore_Storage',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'CommunalStorage': {
+            'hash': 3084373371,
+            'name': 'CommunalStorage'
+          },
+          'PlayerInteractionRestrictor': {
+            'hash': 2951515968,
+            'name': 'PlayerInteractionRestrictor'
+          }
+        }
+      },
+      'Withdraw_Dock_34750': {
+        'hash': 34750,
+        'name': 'Withdraw_Dock',
+        'savables': {}
+      }
+    }
+  },
+  'Ore_Training': {
+    'hash': 56300,
+    'name': 'Ore_Training',
+    'embedded': {
+      'Ore_Training_56294': {
+        'hash': 56294,
+        'name': 'Ore_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Outdoor_Light_Fixture': {
+    'hash': 4686,
+    'name': 'Outdoor_Light_Fixture',
+    'embedded': {
+      'Fire_53718': {
+        'hash': 53718,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Outdoor_Light_Fixture_2808': {
+        'hash': 2808,
+        'name': 'Outdoor_Light_Fixture',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Outdoor_Light_Fixture_Dim': {
+    'hash': 2758,
+    'name': 'Outdoor_Light_Fixture_Dim',
+    'embedded': {
+      'Fire_34930': {
+        'hash': 34930,
+        'name': 'Fire',
+        'savables': {}
+      },
+      'Outdoor_Light_Fixture_Dim_2756': {
+        'hash': 2756,
+        'name': 'Outdoor_Light_Fixture_Dim',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Padlock_Standard': {
+    'hash': 3830,
+    'name': 'Padlock_Standard',
+    'embedded': {
+      'Padlock_Standard_8924': {
+        'hash': 8924,
+        'name': 'Padlock_Standard',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Page': {
+    'hash': 40320,
+    'name': 'Page',
+    'embedded': {}
+  },
+  'Paper': {
+    'hash': 37066,
+    'name': 'Paper',
+    'embedded': {
+      'Paper_60604': {
+        'hash': 60604,
+        'name': 'Paper',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PaperPageInstance': {
+            'hash': 2241532968,
+            'name': 'PaperPageInstance'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Phantom': {
+    'hash': 17772,
+    'name': 'Phantom',
+    'embedded': {
+      'AI_25864': {
+        'hash': 25864,
+        'name': 'AI',
+        'savables': {}
+      },
+      'Phantom_01_16416': {
+        'hash': 16416,
+        'name': 'Phantom_01',
+        'savables': {}
+      },
+      'Phantom_25882': {
+        'hash': 25882,
+        'name': 'Phantom',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Phantom_Guard': {
+    'hash': 6940,
+    'name': 'Phantom_Guard',
+    'embedded': {
+      'Heat_Point_Collection_56294': {
+        'hash': 56294,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_Craft_39368': {
+        'hash': 39368,
+        'name': 'Insert_SwordType_Craft',
+        'savables': {}
+      },
+      'Phantom_Guard_51546': {
+        'hash': 51546,
+        'name': 'Phantom_Guard',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Multi_39370': {
+        'hash': 39370,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Phantom_Head': {
+    'hash': 43960,
+    'name': 'Phantom_Head',
+    'embedded': {
+      'AI_25864': {
+        'hash': 25864,
+        'name': 'AI',
+        'savables': {}
+      },
+      'Phantom_01_16416': {
+        'hash': 16416,
+        'name': 'Phantom_01',
+        'savables': {}
+      },
+      'Phantom_Head_25882': {
+        'hash': 25882,
+        'name': 'Phantom_Head',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Pick_Axe': {
+    'hash': 61654,
+    'name': 'Pick_Axe',
+    'embedded': {
+      'Pick_Axe_35090': {
+        'hash': 35090,
+        'name': 'Pick_Axe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Pickaxe_Head': {
+    'hash': 35878,
+    'name': 'Pickaxe_Head',
+    'embedded': {
+      'Heat_Point_Collection_14016': {
+        'hash': 14016,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_27166': {
+        'hash': 27166,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      },
+      'Pickaxe_Head_35758': {
+        'hash': 35758,
+        'name': 'Pickaxe_Head',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pickaxe_Training': {
+    'hash': 29706,
+    'name': 'Pickaxe_Training',
+    'embedded': {}
+  },
+  'PickupSlidingDoor': {
+    'hash': 13452,
+    'name': 'PickupSlidingDoor',
+    'embedded': {
+      'Grip_(1)_8328': {
+        'hash': 8328,
+        'name': 'Grip_(1)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(2)_8460': {
+        'hash': 8460,
+        'name': 'Grip_(2)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(3)_8292': {
+        'hash': 8292,
+        'name': 'Grip_(3)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(4)_8306': {
+        'hash': 8306,
+        'name': 'Grip_(4)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(5)_27902': {
+        'hash': 27902,
+        'name': 'Grip_(5)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(6)_27924': {
+        'hash': 27924,
+        'name': 'Grip_(6)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(7)_27886': {
+        'hash': 27886,
+        'name': 'Grip_(7)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(8)_27948': {
+        'hash': 27948,
+        'name': 'Grip_(8)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(9)_27940': {
+        'hash': 27940,
+        'name': 'Grip_(9)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_8438': {
+        'hash': 8438,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'PickupSlidingDoor_13450': {
+        'hash': 13450,
+        'name': 'PickupSlidingDoor',
+        'savables': {
+          'MovePickup': {
+            'hash': 1874870249,
+            'name': 'MovePickup'
+          }
+        }
+      }
+    }
+  },
+  'PillarBridgeRotate': {
+    'hash': 47436,
+    'name': 'PillarBridgeRotate',
+    'embedded': {
+      'PillarBridgeRotate_10812': {
+        'hash': 10812,
+        'name': 'PillarBridgeRotate',
+        'savables': {}
+      },
+      'handle_01_30518': {
+        'hash': 30518,
+        'name': 'handle_01',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'handle_02_30398': {
+        'hash': 30398,
+        'name': 'handle_02',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'handle_03_30390': {
+        'hash': 30390,
+        'name': 'handle_03',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'handle_04_30524': {
+        'hash': 30524,
+        'name': 'handle_04',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'PillarRotate': {
+    'hash': 25648,
+    'name': 'PillarRotate',
+    'embedded': {
+      'PillarRotate_10812': {
+        'hash': 10812,
+        'name': 'PillarRotate',
+        'savables': {}
+      },
+      'handle_01_30158': {
+        'hash': 30158,
+        'name': 'handle_01',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'handle_02_30102': {
+        'hash': 30102,
+        'name': 'handle_02',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'handle_03_30096': {
+        'hash': 30096,
+        'name': 'handle_03',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Pink_Crystal_cluster_02': {
+    'hash': 15424,
+    'name': 'Pink_Crystal_cluster_02',
+    'embedded': {
+      'Pink_Crystal_cluster_02_54416': {
+        'hash': 54416,
+        'name': 'Pink_Crystal_cluster_02',
+        'savables': {}
+      }
+    }
+  },
+  'PlaceItemPuzzleNoDock': {
+    'hash': 12962,
+    'name': 'PlaceItemPuzzleNoDock',
+    'embedded': {
+      'PlaceItemPuzzleNoDock_26668': {
+        'hash': 26668,
+        'name': 'PlaceItemPuzzleNoDock',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PlaceItemNoDockPuzzleLogic': {
+            'hash': 1176706580,
+            'name': 'PlaceItemNoDockPuzzleLogic'
+          }
+        }
+      }
+    }
+  },
+  'PlaceItemPuzzleNoDockFire': {
+    'hash': 64858,
+    'name': 'PlaceItemPuzzleNoDockFire',
+    'embedded': {
+      'PlaceItemPuzzleNoDockFire_54686': {
+        'hash': 54686,
+        'name': 'PlaceItemPuzzleNoDockFire',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PlaceItemNoDockFirePuzzleLogic': {
+            'hash': 2495475500,
+            'name': 'PlaceItemNoDockFirePuzzleLogic'
+          }
+        }
+      }
+    }
+  },
+  'Placed_Table': {
+    'hash': 8520,
+    'name': 'Placed_Table',
+    'embedded': {
+      'Placed_Table_55788': {
+        'hash': 55788,
+        'name': 'Placed_Table',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Object_(1)_45908': {
+        'hash': 45908,
+        'name': 'Spawn_Object_(1)',
+        'savables': {}
+      },
+      'Spawn_Object_(2)_45906': {
+        'hash': 45906,
+        'name': 'Spawn_Object_(2)',
+        'savables': {}
+      },
+      'Spawn_Object_(3)_45904': {
+        'hash': 45904,
+        'name': 'Spawn_Object_(3)',
+        'savables': {}
+      },
+      'Spawn_Object_(4)_45902': {
+        'hash': 45902,
+        'name': 'Spawn_Object_(4)',
+        'savables': {}
+      },
+      'Spawn_Object_45900': {
+        'hash': 45900,
+        'name': 'Spawn_Object',
+        'savables': {}
+      },
+      'table_leg_01_48772': {
+        'hash': 48772,
+        'name': 'table_leg_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_leg_02_48776': {
+        'hash': 48776,
+        'name': 'table_leg_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_leg_03_48784': {
+        'hash': 48784,
+        'name': 'table_leg_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_leg_04_48760': {
+        'hash': 48760,
+        'name': 'table_leg_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_main_48764': {
+        'hash': 48764,
+        'name': 'table_main',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_support_long_01_48780': {
+        'hash': 48780,
+        'name': 'table_support_long_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_support_long_02_48792': {
+        'hash': 48792,
+        'name': 'table_support_long_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_support_short_01_48788': {
+        'hash': 48788,
+        'name': 'table_support_short_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'table_support_short_02_48768': {
+        'hash': 48768,
+        'name': 'table_support_short_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Placement_Crate': {
+    'hash': 36614,
+    'name': 'Placement_Crate',
+    'embedded': {
+      'Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_31842': {
+        'hash': 31842,
+        'name': 'Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_31266': {
+        'hash': 31266,
+        'name': 'Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_4_30878': {
+        'hash': 30878,
+        'name': 'Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Placement_Crate_14764': {
+        'hash': 14764,
+        'name': 'Placement_Crate',
+        'savables': {
+          'GeneratedLoot': {
+            'hash': 3642863935,
+            'name': 'GeneratedLoot'
+          }
+        }
+      }
+    }
+  },
+  'PlayerInAreaLogic': {
+    'hash': 11982,
+    'name': 'PlayerInAreaLogic',
+    'embedded': {
+      'PlayerInAreaLogic_9782': {
+        'hash': 9782,
+        'name': 'PlayerInAreaLogic',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PlayerDetect': {
+            'hash': 403040752,
+            'name': 'PlayerDetect'
+          }
+        }
+      }
+    }
+  },
+  'Player_Template': {
+    'hash': 61646,
+    'name': 'Player_Template',
+    'embedded': {}
+  },
+  'Poison_Cloud': {
+    'hash': 52444,
+    'name': 'Poison_Cloud',
+    'embedded': {
+      'Poison_Cloud_50236': {
+        'hash': 50236,
+        'name': 'Poison_Cloud',
+        'savables': {}
+      }
+    }
+  },
+  'Poison_Vent': {
+    'hash': 37252,
+    'name': 'Poison_Vent',
+    'embedded': {
+      'PoisonSpawn_15766': {
+        'hash': 15766,
+        'name': 'PoisonSpawn',
+        'savables': {
+          'PlayerDetect': {
+            'hash': 403040752,
+            'name': 'PlayerDetect'
+          }
+        }
+      },
+      'Poison_Vent_46584': {
+        'hash': 46584,
+        'name': 'Poison_Vent',
+        'savables': {}
+      }
+    }
+  },
+  'Pole_Hugger_Edgy': {
+    'hash': 17828,
+    'name': 'Pole_Hugger_Edgy',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Pole_Hugger_Edgy_15532': {
+        'hash': 15532,
+        'name': 'Pole_Hugger_Edgy',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pole_Hugger_Pointy_Ends': {
+    'hash': 10962,
+    'name': 'Pole_Hugger_Pointy_Ends',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Pole_Hugger_Pointy_Ends_15532': {
+        'hash': 15532,
+        'name': 'Pole_Hugger_Pointy_Ends',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pole_Hugger_Short': {
+    'hash': 4920,
+    'name': 'Pole_Hugger_Short',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Pole_Hugger_Short_15532': {
+        'hash': 15532,
+        'name': 'Pole_Hugger_Short',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pole_Hugger_Tall': {
+    'hash': 62282,
+    'name': 'Pole_Hugger_Tall',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Pole_Hugger_Tall_15532': {
+        'hash': 15532,
+        'name': 'Pole_Hugger_Tall',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pommel': {
+    'hash': 15658,
+    'name': 'Pommel',
+    'embedded': {
+      'Heat_Point_Collection_58710': {
+        'hash': 58710,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_PommelType_112': {
+        'hash': 112,
+        'name': 'Insert_PommelType',
+        'savables': {}
+      },
+      'Pommel_15532': {
+        'hash': 15532,
+        'name': 'Pommel',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pommel_Circle': {
+    'hash': 57966,
+    'name': 'Pommel_Circle',
+    'embedded': {
+      'Heat_Point_Collection_58958': {
+        'hash': 58958,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_PommelType_112': {
+        'hash': 112,
+        'name': 'Insert_PommelType',
+        'savables': {}
+      },
+      'Pommel_Circle_15532': {
+        'hash': 15532,
+        'name': 'Pommel_Circle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pommel_Cone': {
+    'hash': 52360,
+    'name': 'Pommel_Cone',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Pommel_Cone_15532': {
+        'hash': 15532,
+        'name': 'Pommel_Cone',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pommel_Diamond': {
+    'hash': 42764,
+    'name': 'Pommel_Diamond',
+    'embedded': {
+      'Heat_Point_Collection_59204': {
+        'hash': 59204,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_PommelType_112': {
+        'hash': 112,
+        'name': 'Insert_PommelType',
+        'savables': {}
+      },
+      'Pommel_Diamond_15532': {
+        'hash': 15532,
+        'name': 'Pommel_Diamond',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pommel_Large_Square': {
+    'hash': 42138,
+    'name': 'Pommel_Large_Square',
+    'embedded': {
+      'Heat_Point_Collection_59448': {
+        'hash': 59448,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_PommelType_42136': {
+        'hash': 42136,
+        'name': 'Insert_PommelType',
+        'savables': {}
+      },
+      'Pommel_Large_Square_42132': {
+        'hash': 42132,
+        'name': 'Pommel_Large_Square',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pommel_Squashed': {
+    'hash': 1736,
+    'name': 'Pommel_Squashed',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Pommel_Squashed_15532': {
+        'hash': 15532,
+        'name': 'Pommel_Squashed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Pond_Test': {
+    'hash': 58844,
+    'name': 'Pond_Test',
+    'embedded': {
+      'Heat_Area_15578': {
+        'hash': 15578,
+        'name': 'Heat_Area',
+        'savables': {}
+      },
+      'Pond_Test_21538': {
+        'hash': 21538,
+        'name': 'Pond_Test',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          }
+        }
+      }
+    }
+  },
+  'Pond_Water': {
+    'hash': 23384,
+    'name': 'Pond_Water',
+    'embedded': {
+      'Heat_Area_46624': {
+        'hash': 46624,
+        'name': 'Heat_Area',
+        'savables': {}
+      },
+      'Pond_Water_21272': {
+        'hash': 21272,
+        'name': 'Pond_Water',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          }
+        }
+      }
+    }
+  },
+  'Post_Box': {
+    'hash': 9562,
+    'name': 'Post_Box',
+    'embedded': {
+      'Handle_17172': {
+        'hash': 17172,
+        'name': 'Handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Post_Box_7104': {
+        'hash': 7104,
+        'name': 'Post_Box',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Full_Burnt': {
+    'hash': 1574,
+    'name': 'Potato_Full_Burnt',
+    'embedded': {
+      'Cooking_23418': {
+        'hash': 23418,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Full_Burnt_1198': {
+        'hash': 1198,
+        'name': 'Potato_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Full_Cooked': {
+    'hash': 57840,
+    'name': 'Potato_Full_Cooked',
+    'embedded': {
+      'Cooking_9014': {
+        'hash': 9014,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Full_Cooked_57464': {
+        'hash': 57464,
+        'name': 'Potato_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Full_Ripe': {
+    'hash': 54692,
+    'name': 'Potato_Full_Ripe',
+    'embedded': {
+      'Cooking_11142': {
+        'hash': 11142,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Full_Ripe_54316': {
+        'hash': 54316,
+        'name': 'Potato_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Full_Unripe': {
+    'hash': 52146,
+    'name': 'Potato_Full_Unripe',
+    'embedded': {
+      'Cooking_31548': {
+        'hash': 31548,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Full_Unripe_51770': {
+        'hash': 51770,
+        'name': 'Potato_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Growth': {
+    'hash': 49408,
+    'name': 'Potato_Growth',
+    'embedded': {
+      'Potato_Growth_33458': {
+        'hash': 33458,
+        'name': 'Potato_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Half_Burnt': {
+    'hash': 59748,
+    'name': 'Potato_Half_Burnt',
+    'embedded': {
+      'Cooking_23418': {
+        'hash': 23418,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Cooking_32800': {
+        'hash': 32800,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Half_Burnt_59372': {
+        'hash': 59372,
+        'name': 'Potato_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Half_Cooked': {
+    'hash': 50612,
+    'name': 'Potato_Half_Cooked',
+    'embedded': {
+      'Cooking_32982': {
+        'hash': 32982,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Cooking_9014': {
+        'hash': 9014,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Half_Cooked_50236': {
+        'hash': 50236,
+        'name': 'Potato_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Half_Ripe': {
+    'hash': 48134,
+    'name': 'Potato_Half_Ripe',
+    'embedded': {
+      'Cooking_11142': {
+        'hash': 11142,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Cooking_33006': {
+        'hash': 33006,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Half_Ripe_47758': {
+        'hash': 47758,
+        'name': 'Potato_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Half_Unripe': {
+    'hash': 45822,
+    'name': 'Potato_Half_Unripe',
+    'embedded': {
+      'Cooking_31548': {
+        'hash': 31548,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Cooking_33396': {
+        'hash': 33396,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Potato_Half_Unripe_45446': {
+        'hash': 45446,
+        'name': 'Potato_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Plant_Growth': {
+    'hash': 15786,
+    'name': 'Potato_Plant_Growth',
+    'embedded': {
+      'Potato_Plant_Growth_33458': {
+        'hash': 33458,
+        'name': 'Potato_Plant_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Plant_Stage_1': {
+    'hash': 62602,
+    'name': 'Potato_Plant_Stage_1',
+    'embedded': {
+      'Potato_Plant_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Potato_Plant_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Potato_Plant_Stage_2': {
+    'hash': 63530,
+    'name': 'Potato_Plant_Stage_2',
+    'embedded': {
+      'Potato_Plant_Stage_2_63514': {
+        'hash': 63514,
+        'name': 'Potato_Plant_Stage_2',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Plant_Stage_3': {
+    'hash': 54788,
+    'name': 'Potato_Plant_Stage_3',
+    'embedded': {
+      'Potato_Plant_Stage_3_54748': {
+        'hash': 54748,
+        'name': 'Potato_Plant_Stage_3',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Potato_Puree_Recipe_Burnt_Stew': {
+    'hash': 57936,
+    'name': 'Potato_Puree_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Potato_Puree_Recipe_Cooked_Stew': {
+    'hash': 57960,
+    'name': 'Potato_Puree_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Potato_Puree_Recipe_Raw_Stew': {
+    'hash': 57918,
+    'name': 'Potato_Puree_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Potato_Sapling': {
+    'hash': 50692,
+    'name': 'Potato_Sapling',
+    'embedded': {
+      'Potato_Sapling_52858': {
+        'hash': 52858,
+        'name': 'Potato_Sapling',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Potatoes_29060': {
+        'hash': 29060,
+        'name': 'Potatoes',
+        'savables': {
+          'GrowerGroup': {
+            'hash': 2363255897,
+            'name': 'GrowerGroup'
+          }
+        }
+      }
+    }
+  },
+  'Potion_Hoops_Side_Tool_Attachment': {
+    'hash': 31418,
+    'name': 'Potion_Hoops_Side_Tool_Attachment',
+    'embedded': {
+      'Dock_Mid_31416': {
+        'hash': 31416,
+        'name': 'Dock_Mid',
+        'savables': {
+          'AdditionalOwnedDock': {
+            'hash': 2592242915,
+            'name': 'AdditionalOwnedDock'
+          }
+        }
+      },
+      'Dock_Side_21918': {
+        'hash': 21918,
+        'name': 'Dock_Side',
+        'savables': {
+          'AdditionalOwnedDock': {
+            'hash': 2592242915,
+            'name': 'AdditionalOwnedDock'
+          }
+        }
+      },
+      'Dock_Side_22020': {
+        'hash': 22020,
+        'name': 'Dock_Side',
+        'savables': {
+          'AdditionalOwnedDock': {
+            'hash': 2592242915,
+            'name': 'AdditionalOwnedDock'
+          }
+        }
+      },
+      'Insert_Bag_Attach_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Attach',
+        'savables': {}
+      },
+      'Potion_Hoops_Side_Tool_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Potion_Hoops_Side_Tool_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Storage_53262': {
+        'hash': 53262,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'potionHoops_sideTool_pad_01_30876': {
+        'hash': 30876,
+        'name': 'potionHoops_sideTool_pad_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'potionHoops_sideTool_ringHolder_29430': {
+        'hash': 29430,
+        'name': 'potionHoops_sideTool_ringHolder',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'potionHoops_sideTool_ringPin_01_30888': {
+        'hash': 30888,
+        'name': 'potionHoops_sideTool_ringPin_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'potionHoops_sideTool_ringPin_02_30884': {
+        'hash': 30884,
+        'name': 'potionHoops_sideTool_ringPin_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'potionHoops_sideTool_ringPin_03_30892': {
+        'hash': 30892,
+        'name': 'potionHoops_sideTool_ringPin_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'potionHoops_sideTool_strap_01_30880': {
+        'hash': 30880,
+        'name': 'potionHoops_sideTool_strap_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Potion_Medium': {
+    'hash': 23644,
+    'name': 'Potion_Medium',
+    'embedded': {
+      'CapPickup_21290': {
+        'hash': 21290,
+        'name': 'CapPickup',
+        'savables': {
+          'CapPickup': {
+            'hash': 3082855726,
+            'name': 'CapPickup'
+          }
+        }
+      },
+      'Potion_Medium_23646': {
+        'hash': 23646,
+        'name': 'Potion_Medium',
+        'savables': {
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Potion_Small': {
+    'hash': 62934,
+    'name': 'Potion_Small',
+    'embedded': {}
+  },
+  'Pouch': {
+    'hash': 38942,
+    'name': 'Pouch',
+    'embedded': {
+      'Pouch_36072': {
+        'hash': 36072,
+        'name': 'Pouch',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Storage_36080': {
+        'hash': 36080,
+        'name': 'Storage',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Pouch_Training': {
+    'hash': 57348,
+    'name': 'Pouch_Training',
+    'embedded': {
+      'Pouch_Training_36072': {
+        'hash': 36072,
+        'name': 'Pouch_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Storage_65008': {
+        'hash': 65008,
+        'name': 'Storage',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Poultry_Onion_Mushroom_Recipe_Burnt_Stew': {
+    'hash': 57780,
+    'name': 'Poultry_Onion_Mushroom_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Poultry_Onion_Mushroom_Recipe_Cooked_Stew': {
+    'hash': 57762,
+    'name': 'Poultry_Onion_Mushroom_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Poultry_Onion_Mushroom_Recipe_Raw_Stew': {
+    'hash': 57804,
+    'name': 'Poultry_Onion_Mushroom_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Poultry_Potato_Recipe_Burnt_Stew': {
+    'hash': 57894,
+    'name': 'Poultry_Potato_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Poultry_Potato_Recipe_Cooked_Stew': {
+    'hash': 57852,
+    'name': 'Poultry_Potato_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Poultry_Potato_Recipe_Raw_Stew': {
+    'hash': 57876,
+    'name': 'Poultry_Potato_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Poultry_Recipe_Burnt_Stew': {
+    'hash': 10830,
+    'name': 'Poultry_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Poultry_Recipe_Cooked_Stew': {
+    'hash': 11448,
+    'name': 'Poultry_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Poultry_Recipe_Raw_Stew': {
+    'hash': 12132,
+    'name': 'Poultry_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Power_Strike_Counter': {
+    'hash': 37516,
+    'name': 'Power_Strike_Counter',
+    'embedded': {
+      'Power_Strike_Counter_63778': {
+        'hash': 63778,
+        'name': 'Power_Strike_Counter',
+        'savables': {}
+      }
+    }
+  },
+  'Practice_Gate': {
+    'hash': 64704,
+    'name': 'Practice_Gate',
+    'embedded': {}
+  },
+  'Profession_Upgrade_Shrine': {
+    'hash': 32200,
+    'name': 'Profession_Upgrade_Shrine',
+    'embedded': {
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'Landscape_Finder_33664': {
+        'hash': 33664,
+        'name': 'Landscape_Finder',
+        'savables': {
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          }
+        }
+      },
+      'Profession_Upgrade_Shrine_53594': {
+        'hash': 53594,
+        'name': 'Profession_Upgrade_Shrine',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'SkillShrine': {
+            'hash': 2190886200,
+            'name': 'SkillShrine'
+          }
+        }
+      },
+      'Testing_Area_29220': {
+        'hash': 29220,
+        'name': 'Testing_Area',
+        'savables': {}
+      }
+    }
+  },
+  'Prongs': {
+    'hash': 40460,
+    'name': 'Prongs',
+    'embedded': {
+      'Prongs_13190': {
+        'hash': 13190,
+        'name': 'Prongs',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Weapon_Dock_5626': {
+        'hash': 5626,
+        'name': 'Weapon_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Proto_Greater_Got_Bramble_Wall': {
+    'hash': 34050,
+    'name': 'Proto_Greater_Got_Bramble_Wall',
+    'embedded': {
+      'Proto_Greater_Got_Bramble_Wall_34034': {
+        'hash': 34034,
+        'name': 'Proto_Greater_Got_Bramble_Wall',
+        'savables': {}
+      }
+    }
+  },
+  'Pumpkin_Growth': {
+    'hash': 59922,
+    'name': 'Pumpkin_Growth',
+    'embedded': {
+      'Pumpkin_Growth_33458': {
+        'hash': 33458,
+        'name': 'Pumpkin_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Pumpkin_Recipe_Burnt_Stew': {
+    'hash': 62678,
+    'name': 'Pumpkin_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Pumpkin_Recipe_Cooked_Stew': {
+    'hash': 62694,
+    'name': 'Pumpkin_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Pumpkin_Recipe_Raw_Stew': {
+    'hash': 62724,
+    'name': 'Pumpkin_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Pumpkin_Tree': {
+    'hash': 49086,
+    'name': 'Pumpkin_Tree',
+    'embedded': {
+      'Pumpkin_Tree_46510': {
+        'hash': 46510,
+        'name': 'Pumpkin_Tree',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Pumpkin_Tree_Growth': {
+    'hash': 41658,
+    'name': 'Pumpkin_Tree_Growth',
+    'embedded': {
+      'Pumpkin_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Pumpkin_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Pumpkin_Tree_Separated': {
+    'hash': 23566,
+    'name': 'Pumpkin_Tree_Separated',
+    'embedded': {}
+  },
+  'Pumpkin_Tree_Stage_1': {
+    'hash': 38672,
+    'name': 'Pumpkin_Tree_Stage_1',
+    'embedded': {
+      'Pumpkin_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Pumpkin_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Pumpkin_Tree_Stage_2': {
+    'hash': 42508,
+    'name': 'Pumpkin_Tree_Stage_2',
+    'embedded': {
+      'Pumpkin_Tree_Stage_2_46510': {
+        'hash': 46510,
+        'name': 'Pumpkin_Tree_Stage_2',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Pumpkin_Tree_Stage_3': {
+    'hash': 63038,
+    'name': 'Pumpkin_Tree_Stage_3',
+    'embedded': {
+      'Pumpkin_Tree_Stage_3_46510': {
+        'hash': 46510,
+        'name': 'Pumpkin_Tree_Stage_3',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Puzzle_Orb_1': {
+    'hash': 31620,
+    'name': 'Puzzle_Orb_1',
+    'embedded': {
+      'Puzzle_Orb_1_11514': {
+        'hash': 11514,
+        'name': 'Puzzle_Orb_1',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Puzzle_Orb_2': {
+    'hash': 47150,
+    'name': 'Puzzle_Orb_2',
+    'embedded': {
+      'Puzzle_Orb_2_11514': {
+        'hash': 11514,
+        'name': 'Puzzle_Orb_2',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Puzzle_Orb_Restrictor': {
+    'hash': 29276,
+    'name': 'Puzzle_Orb_Restrictor',
+    'embedded': {
+      'Puzzle_Orb_Restrictor_29424': {
+        'hash': 29424,
+        'name': 'Puzzle_Orb_Restrictor',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PositionRestrictor': {
+            'hash': 1776498660,
+            'name': 'PositionRestrictor'
+          }
+        }
+      }
+    }
+  },
+  'Puzzle_Pillar_with_Wheel_Bridge': {
+    'hash': 15908,
+    'name': 'Puzzle_Pillar_with_Wheel_Bridge',
+    'embedded': {
+      'Elevator_20982': {
+        'hash': 20982,
+        'name': 'Elevator',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      },
+      'Grip_(1)_54050': {
+        'hash': 54050,
+        'name': 'Grip_(1)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(2)_54614': {
+        'hash': 54614,
+        'name': 'Grip_(2)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(3)_56370': {
+        'hash': 56370,
+        'name': 'Grip_(3)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(4)_53470': {
+        'hash': 53470,
+        'name': 'Grip_(4)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(5)_19654': {
+        'hash': 19654,
+        'name': 'Grip_(5)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_56728': {
+        'hash': 56728,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Puzzle_Pillar_with_Wheel_Bridge_31136': {
+        'hash': 31136,
+        'name': 'Puzzle_Pillar_with_Wheel_Bridge',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          }
+        }
+      },
+      'WheelBridge(Clone)_43884': {
+        'hash': 43884,
+        'name': 'WheelBridge(Clone)',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          },
+          'RotatePickup': {
+            'hash': 2498617949,
+            'name': 'RotatePickup'
+          }
+        }
+      },
+      'wheel_origin_43868': {
+        'hash': 43868,
+        'name': 'wheel_origin',
+        'savables': {
+          'WheelGrab': {
+            'hash': 320224849,
+            'name': 'WheelGrab'
+          }
+        }
+      }
+    }
+  },
+  'Quest_Board': {
+    'hash': 57298,
+    'name': 'Quest_Board',
+    'embedded': {
+      'Quest_Board_57352': {
+        'hash': 57352,
+        'name': 'Quest_Board',
+        'savables': {}
+      }
+    }
+  },
+  'Quiver': {
+    'hash': 64640,
+    'name': 'Quiver',
+    'embedded': {
+      'Dock_33558': {
+        'hash': 33558,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Quiver_33568': {
+        'hash': 33568,
+        'name': 'Quiver',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'standard_quiver_body_49088': {
+        'hash': 49088,
+        'name': 'standard_quiver_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_body_laces_01_43824': {
+        'hash': 43824,
+        'name': 'standard_quiver_body_laces_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_body_lipBlock_49092': {
+        'hash': 49092,
+        'name': 'standard_quiver_body_lipBlock',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_metalRingBottom_49080': {
+        'hash': 49080,
+        'name': 'standard_quiver_metalRingBottom',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_metalRingTop_49084': {
+        'hash': 49084,
+        'name': 'standard_quiver_metalRingTop',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_strap_49068': {
+        'hash': 49068,
+        'name': 'standard_quiver_strap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_strap_clasp_01_49072': {
+        'hash': 49072,
+        'name': 'standard_quiver_strap_clasp_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_strap_clasp_02_49076': {
+        'hash': 49076,
+        'name': 'standard_quiver_strap_clasp_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_quiver_strap_wraps_43820': {
+        'hash': 43820,
+        'name': 'standard_quiver_strap_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Random_Placement_Crate': {
+    'hash': 8246,
+    'name': 'Random_Placement_Crate',
+    'embedded': {
+      'Crate_place(Clone)_14764': {
+        'hash': 14764,
+        'name': 'Crate_place(Clone)',
+        'savables': {
+          'GeneratedLoot': {
+            'hash': 3642863935,
+            'name': 'GeneratedLoot'
+          }
+        }
+      },
+      'Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_31842': {
+        'hash': 31842,
+        'name': 'Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_31266': {
+        'hash': 31266,
+        'name': 'Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_4_30878': {
+        'hash': 30878,
+        'name': 'Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Random_Placement_Crate_14764': {
+        'hash': 14764,
+        'name': 'Random_Placement_Crate',
+        'savables': {}
+      }
+    }
+  },
+  'Random_Spawn_Rectangle': {
+    'hash': 24644,
+    'name': 'Random_Spawn_Rectangle',
+    'embedded': {}
+  },
+  'Rapier_Blade': {
+    'hash': 11332,
+    'name': 'Rapier_Blade',
+    'embedded': {
+      'Heat_Point_Collection_63016': {
+        'hash': 63016,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'Rapier_Blade_35392': {
+        'hash': 35392,
+        'name': 'Rapier_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'metal_blade_rapier_full_geo_LOD0_6834': {
+        'hash': 6834,
+        'name': 'metal_blade_rapier_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Recycler': {
+    'hash': 60684,
+    'name': 'Recycler',
+    'embedded': {
+      'Display_Dock_6940': {
+        'hash': 6940,
+        'name': 'Display_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Display_Dock_6988': {
+        'hash': 6988,
+        'name': 'Display_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Display_Dock_6992': {
+        'hash': 6992,
+        'name': 'Display_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Fuel_54958': {
+        'hash': 54958,
+        'name': 'Dock_Fuel',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Output_44868': {
+        'hash': 44868,
+        'name': 'Dock_Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Output_58172': {
+        'hash': 58172,
+        'name': 'Dock_Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Output_61316': {
+        'hash': 61316,
+        'name': 'Dock_Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_24422': {
+        'hash': 24422,
+        'name': 'Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_6394': {
+        'hash': 6394,
+        'name': 'Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'HeatArea_37766': {
+        'hash': 37766,
+        'name': 'HeatArea',
+        'savables': {}
+      },
+      'Recycler_57752': {
+        'hash': 57752,
+        'name': 'Recycler',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'Recycler': {
+            'hash': 2450553269,
+            'name': 'Recycler'
+          }
+        }
+      },
+      'recycler_fuelHatch_37522': {
+        'hash': 37522,
+        'name': 'recycler_fuelHatch',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'smelter_bellows_arm_jnt_25672': {
+        'hash': 25672,
+        'name': 'smelter_bellows_arm_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Red_Iron_Ingot': {
+    'hash': 31034,
+    'name': 'Red_Iron_Ingot',
+    'embedded': {
+      'Heat_Point_Collection_13552': {
+        'hash': 13552,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Red_Iron_Ingot_32738': {
+        'hash': 32738,
+        'name': 'Red_Iron_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Red_Mushroom_Recipe_Burnt_Stew': {
+    'hash': 63290,
+    'name': 'Red_Mushroom_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Red_Mushroom_Recipe_Cooked_Stew': {
+    'hash': 62660,
+    'name': 'Red_Mushroom_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Red_Mushroom_Recipe_Raw_Stew': {
+    'hash': 62024,
+    'name': 'Red_Mushroom_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Red_Mushroom_Shield': {
+    'hash': 49188,
+    'name': 'Red_Mushroom_Shield',
+    'embedded': {
+      'Red_Mushroom_Shield_49190': {
+        'hash': 49190,
+        'name': 'Red_Mushroom_Shield',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Red_Sauce_Recipe_Burnt_Stew': {
+    'hash': 57978,
+    'name': 'Red_Sauce_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Red_Sauce_Recipe_Cooked_Stew': {
+    'hash': 58026,
+    'name': 'Red_Sauce_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Red_Sauce_Recipe_Raw_Stew': {
+    'hash': 58002,
+    'name': 'Red_Sauce_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Redwood_Gotera_Core': {
+    'hash': 41402,
+    'name': 'Redwood_Gotera_Core',
+    'embedded': {
+      'Redwood_Gotera_Core_41418': {
+        'hash': 41418,
+        'name': 'Redwood_Gotera_Core',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Redwood_Tree_Growth': {
+    'hash': 48248,
+    'name': 'Redwood_Tree_Growth',
+    'embedded': {
+      'Redwood_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Redwood_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Redwood_Tree_Seed': {
+    'hash': 55054,
+    'name': 'Redwood_Tree_Seed',
+    'embedded': {
+      'Redwood_Tree_Seed_35258': {
+        'hash': 35258,
+        'name': 'Redwood_Tree_Seed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Redwood_Tree_Stage_1': {
+    'hash': 17526,
+    'name': 'Redwood_Tree_Stage_1',
+    'embedded': {
+      'Redwood_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Redwood_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Repair_Box': {
+    'hash': 3458,
+    'name': 'Repair_Box',
+    'embedded': {
+      'Cost_1_22852': {
+        'hash': 22852,
+        'name': 'Cost_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_2_22786': {
+        'hash': 22786,
+        'name': 'Cost_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_3_22772': {
+        'hash': 22772,
+        'name': 'Cost_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_1_22642': {
+        'hash': 22642,
+        'name': 'Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_22692': {
+        'hash': 22692,
+        'name': 'Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_22698': {
+        'hash': 22698,
+        'name': 'Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Landmark_Finder_5660': {
+        'hash': 5660,
+        'name': 'Landmark_Finder',
+        'savables': {
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          }
+        }
+      },
+      'Quest_Marker_-_Repair_Box_51948': {
+        'hash': 51948,
+        'name': 'Quest_Marker_-_Repair_Box',
+        'savables': {
+          'ManualCondition': {
+            'hash': 1268269765,
+            'name': 'ManualCondition'
+          },
+          'RepairableObjectComparisonCondition': {
+            'hash': 1558189723,
+            'name': 'RepairableObjectComparisonCondition'
+          }
+        }
+      },
+      'RepairBox_15188': {
+        'hash': 15188,
+        'name': 'RepairBox',
+        'savables': {}
+      },
+      'Repair_Box_65496': {
+        'hash': 65496,
+        'name': 'Repair_Box',
+        'savables': {
+          'RepairBox': {
+            'hash': 3820454400,
+            'name': 'RepairBox'
+          }
+        }
+      }
+    }
+  },
+  'Repair_Box_Standing_Panel': {
+    'hash': 32704,
+    'name': 'Repair_Box_Standing_Panel',
+    'embedded': {
+      'Cost_1_32664': {
+        'hash': 32664,
+        'name': 'Cost_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_2_32662': {
+        'hash': 32662,
+        'name': 'Cost_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_3_32660': {
+        'hash': 32660,
+        'name': 'Cost_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_1_32654': {
+        'hash': 32654,
+        'name': 'Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_32656': {
+        'hash': 32656,
+        'name': 'Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_32658': {
+        'hash': 32658,
+        'name': 'Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Landmark_Finder_4224': {
+        'hash': 4224,
+        'name': 'Landmark_Finder',
+        'savables': {
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          }
+        }
+      },
+      'Quest_Marker_-_Repair_Box_51948': {
+        'hash': 51948,
+        'name': 'Quest_Marker_-_Repair_Box',
+        'savables': {
+          'ManualCondition': {
+            'hash': 1268269765,
+            'name': 'ManualCondition'
+          },
+          'RepairableObjectComparisonCondition': {
+            'hash': 1558189723,
+            'name': 'RepairableObjectComparisonCondition'
+          }
+        }
+      },
+      'RepairBox_15188': {
+        'hash': 15188,
+        'name': 'RepairBox',
+        'savables': {}
+      },
+      'Repair_Box_Standing_Panel_32702': {
+        'hash': 32702,
+        'name': 'Repair_Box_Standing_Panel',
+        'savables': {
+          'RepairBox': {
+            'hash': 3820454400,
+            'name': 'RepairBox'
+          }
+        }
+      }
+    }
+  },
+  'Repair_Box_Wall_Panel': {
+    'hash': 41842,
+    'name': 'Repair_Box_Wall_Panel',
+    'embedded': {
+      'Cost_1_41802': {
+        'hash': 41802,
+        'name': 'Cost_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_2_41800': {
+        'hash': 41800,
+        'name': 'Cost_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_3_41798': {
+        'hash': 41798,
+        'name': 'Cost_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_1_41792': {
+        'hash': 41792,
+        'name': 'Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_41794': {
+        'hash': 41794,
+        'name': 'Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_41796': {
+        'hash': 41796,
+        'name': 'Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Landmark_Finder_3504': {
+        'hash': 3504,
+        'name': 'Landmark_Finder',
+        'savables': {
+          'Landmark': {
+            'hash': 2590537994,
+            'name': 'Landmark'
+          },
+          'LandmarkDiscoverZone': {
+            'hash': 4095875831,
+            'name': 'LandmarkDiscoverZone'
+          }
+        }
+      },
+      'Quest_Marker_-_Repair_Box_51948': {
+        'hash': 51948,
+        'name': 'Quest_Marker_-_Repair_Box',
+        'savables': {
+          'ManualCondition': {
+            'hash': 1268269765,
+            'name': 'ManualCondition'
+          },
+          'RepairableObjectComparisonCondition': {
+            'hash': 1558189723,
+            'name': 'RepairableObjectComparisonCondition'
+          }
+        }
+      },
+      'RepairBox_15188': {
+        'hash': 15188,
+        'name': 'RepairBox',
+        'savables': {}
+      },
+      'Repair_Box_Wall_Panel_41840': {
+        'hash': 41840,
+        'name': 'Repair_Box_Wall_Panel',
+        'savables': {
+          'RepairBox': {
+            'hash': 3820454400,
+            'name': 'RepairBox'
+          }
+        }
+      }
+    }
+  },
+  'Repeater': {
+    'hash': 40046,
+    'name': 'Repeater',
+    'embedded': {}
+  },
+  'Rock_Boulder_01': {
+    'hash': 63838,
+    'name': 'Rock_Boulder_01',
+    'embedded': {}
+  },
+  'Rock_Boulder_02': {
+    'hash': 63828,
+    'name': 'Rock_Boulder_02',
+    'embedded': {}
+  },
+  'Rock_Boulder_03': {
+    'hash': 63836,
+    'name': 'Rock_Boulder_03',
+    'embedded': {}
+  },
+  'Rock_Boulder_04': {
+    'hash': 63834,
+    'name': 'Rock_Boulder_04',
+    'embedded': {}
+  },
+  'Rock_Cluster': {
+    'hash': 63824,
+    'name': 'Rock_Cluster',
+    'embedded': {
+      'Rock_Cluster_18314': {
+        'hash': 18314,
+        'name': 'Rock_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Rock_Cluster_Tutorial': {
+    'hash': 25922,
+    'name': 'Rock_Cluster_Tutorial',
+    'embedded': {
+      'Rock_Cluster_Tutorial_18314': {
+        'hash': 18314,
+        'name': 'Rock_Cluster_Tutorial',
+        'savables': {}
+      }
+    }
+  },
+  'Rock_Spire_Gcore_Dynamic': {
+    'hash': 40128,
+    'name': 'Rock_Spire_Gcore_Dynamic',
+    'embedded': {
+      'Death_Fern_Spawner_32170': {
+        'hash': 32170,
+        'name': 'Death_Fern_Spawner',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Health_Vine_Spawner_39788': {
+        'hash': 39788,
+        'name': 'Health_Vine_Spawner',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Rock_Spire_Gcore_Dynamic_23456': {
+        'hash': 23456,
+        'name': 'Rock_Spire_Gcore_Dynamic',
+        'savables': {}
+      },
+      'Vine_Boulder_Spawner_53936': {
+        'hash': 53936,
+        'name': 'Vine_Boulder_Spawner',
+        'savables': {
+          'CylindricalBoundsSurface': {
+            'hash': 34507654,
+            'name': 'CylindricalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Rock_WallBoulder_02': {
+    'hash': 63832,
+    'name': 'Rock_WallBoulder_02',
+    'embedded': {}
+  },
+  'Rod_Long': {
+    'hash': 44066,
+    'name': 'Rod_Long',
+    'embedded': {
+      'Dock_32818': {
+        'hash': 32818,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Rod_Long_24200': {
+        'hash': 24200,
+        'name': 'Rod_Long',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_AxeType_37426': {
+        'hash': 37426,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_31944': {
+        'hash': 31944,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_53940': {
+        'hash': 53940,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Rod_Medium': {
+    'hash': 44204,
+    'name': 'Rod_Medium',
+    'embedded': {
+      'Dock_32818': {
+        'hash': 32818,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Rod_Medium_44084': {
+        'hash': 44084,
+        'name': 'Rod_Medium',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_AxeType_15522': {
+        'hash': 15522,
+        'name': 'Slot_AxeType',
+        'savables': {}
+      },
+      'Slot_Deco_37438': {
+        'hash': 37438,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_EdgeType_Craft_35298': {
+        'hash': 35298,
+        'name': 'Slot_EdgeType_Craft',
+        'savables': {}
+      },
+      'Slot_Multi_31156': {
+        'hash': 31156,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Multi_39008': {
+        'hash': 39008,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Rod_Slim_40cm': {
+    'hash': 59588,
+    'name': 'Rod_Slim_40cm',
+    'embedded': {
+      'Rod_Slim_40cm_37330': {
+        'hash': 37330,
+        'name': 'Rod_Slim_40cm',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Slot_Multi_44690': {
+        'hash': 44690,
+        'name': 'Slot_Multi',
+        'savables': {}
+      }
+    }
+  },
+  'Rope_Clump': {
+    'hash': 43836,
+    'name': 'Rope_Clump',
+    'embedded': {
+      'Rope_Clump_47776': {
+        'hash': 47776,
+        'name': 'Rope_Clump',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rope_Pully_Puzzle': {
+    'hash': 51434,
+    'name': 'Rope_Pully_Puzzle',
+    'embedded': {
+      'Rope_Grab_57800': {
+        'hash': 57800,
+        'name': 'Rope_Grab',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'RopeGrab': {
+            'hash': 237360636,
+            'name': 'RopeGrab'
+          }
+        }
+      },
+      'Rope_Length_57794': {
+        'hash': 57794,
+        'name': 'Rope_Length',
+        'savables': {}
+      },
+      'Rope_Pully_Puzzle_4580': {
+        'hash': 4580,
+        'name': 'Rope_Pully_Puzzle',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          }
+        }
+      }
+    }
+  },
+  'Ruins_Elevator_Puzzle_Square': {
+    'hash': 27582,
+    'name': 'Ruins_Elevator_Puzzle_Square',
+    'embedded': {
+      'Ruins_Elevator_Puzzle_Square_31136': {
+        'hash': 31136,
+        'name': 'Ruins_Elevator_Puzzle_Square',
+        'savables': {}
+      }
+    }
+  },
+  'Ruins_Elevator_Puzzle_Square_Crystal_Pillar': {
+    'hash': 3512,
+    'name': 'Ruins_Elevator_Puzzle_Square_Crystal_Pillar',
+    'embedded': {
+      'Crystal_Blue(Clone)_(1)_40232': {
+        'hash': 40232,
+        'name': 'Crystal_Blue(Clone)_(1)',
+        'savables': {}
+      },
+      'Elevator_20982': {
+        'hash': 20982,
+        'name': 'Elevator',
+        'savables': {
+          'WayPointPath': {
+            'hash': 1063725326,
+            'name': 'WayPointPath'
+          }
+        }
+      },
+      'Ruins_Elevator_Puzzle_Square_Crystal_Pillar_31136': {
+        'hash': 31136,
+        'name': 'Ruins_Elevator_Puzzle_Square_Crystal_Pillar',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Ruins_Elevator_Puzzle_Square_Large_Variant': {
+    'hash': 4192,
+    'name': 'Ruins_Elevator_Puzzle_Square_Large_Variant',
+    'embedded': {
+      'Ruins_Elevator_Puzzle_Square_Large_Variant_16752': {
+        'hash': 16752,
+        'name': 'Ruins_Elevator_Puzzle_Square_Large_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Ruins_Elevator_Puzzle_Square_Pillar_Variant': {
+    'hash': 22284,
+    'name': 'Ruins_Elevator_Puzzle_Square_Pillar_Variant',
+    'embedded': {
+      'Ruins_Elevator_Puzzle_Square_Pillar_Variant_31136': {
+        'hash': 31136,
+        'name': 'Ruins_Elevator_Puzzle_Square_Pillar_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Ruins_Hand_Touch_Activator': {
+    'hash': 1002,
+    'name': 'Ruins_Hand_Touch_Activator',
+    'embedded': {
+      'Ruins_Hand_Touch_Activator_46540': {
+        'hash': 46540,
+        'name': 'Ruins_Hand_Touch_Activator',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      }
+    }
+  },
+  'Ruins_Pillar_Crystal': {
+    'hash': 58240,
+    'name': 'Ruins_Pillar_Crystal',
+    'embedded': {
+      'Crystal_Blue(Clone)_(1)_40232': {
+        'hash': 40232,
+        'name': 'Crystal_Blue(Clone)_(1)',
+        'savables': {}
+      },
+      'Ruins_Pillar_Crystal_58176': {
+        'hash': 58176,
+        'name': 'Ruins_Pillar_Crystal',
+        'savables': {}
+      }
+    }
+  },
+  'Ruins_Sliding_Wall_Puzzle_Square': {
+    'hash': 42494,
+    'name': 'Ruins_Sliding_Wall_Puzzle_Square',
+    'embedded': {
+      'Ruins_Sliding_Wall_Puzzle_Square_42408': {
+        'hash': 42408,
+        'name': 'Ruins_Sliding_Wall_Puzzle_Square',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SlidingDoor': {
+            'hash': 3583462804,
+            'name': 'SlidingDoor'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Axe': {
+    'hash': 4412,
+    'name': 'Rusty_Axe',
+    'embedded': {
+      'Rusty_Axe_62196': {
+        'hash': 62196,
+        'name': 'Rusty_Axe',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Chisel': {
+    'hash': 40366,
+    'name': 'Rusty_Chisel',
+    'embedded': {
+      'Rusty_Chisel_40156': {
+        'hash': 40156,
+        'name': 'Rusty_Chisel',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Greataxe': {
+    'hash': 29296,
+    'name': 'Rusty_Greataxe',
+    'embedded': {
+      'Rusty_Greataxe_28996': {
+        'hash': 28996,
+        'name': 'Rusty_Greataxe',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Greatsword': {
+    'hash': 63156,
+    'name': 'Rusty_Greatsword',
+    'embedded': {
+      'Rusty_Greatsword_62946': {
+        'hash': 62946,
+        'name': 'Rusty_Greatsword',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Hammer': {
+    'hash': 36126,
+    'name': 'Rusty_Hammer',
+    'embedded': {
+      'Rusty_Hammer_58538': {
+        'hash': 58538,
+        'name': 'Rusty_Hammer',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Pickaxe': {
+    'hash': 46874,
+    'name': 'Rusty_Pickaxe',
+    'embedded': {
+      'Rusty_Pickaxe_46574': {
+        'hash': 46574,
+        'name': 'Rusty_Pickaxe',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Pitchfork': {
+    'hash': 59586,
+    'name': 'Rusty_Pitchfork',
+    'embedded': {
+      'Rusty_Pitchfork_58914': {
+        'hash': 58914,
+        'name': 'Rusty_Pitchfork',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Shield': {
+    'hash': 20684,
+    'name': 'Rusty_Shield',
+    'embedded': {
+      'Insert_Shield_64244': {
+        'hash': 64244,
+        'name': 'Insert_Shield',
+        'savables': {}
+      },
+      'Rusty_Shield_20260': {
+        'hash': 20260,
+        'name': 'Rusty_Shield',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Short_Sword': {
+    'hash': 44824,
+    'name': 'Rusty_Short_Sword',
+    'embedded': {
+      'Rusty_Short_Sword_52378': {
+        'hash': 52378,
+        'name': 'Rusty_Short_Sword',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Rusty_Spade': {
+    'hash': 33230,
+    'name': 'Rusty_Spade',
+    'embedded': {
+      'Fake_Pickup_6096': {
+        'hash': 6096,
+        'name': 'Fake_Pickup',
+        'savables': {}
+      },
+      'Rusty_Spade_60654': {
+        'hash': 60654,
+        'name': 'Rusty_Spade',
+        'savables': {
+          'DiggingImpactor': {
+            'hash': 3445325106,
+            'name': 'DiggingImpactor'
+          },
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Safe_Point': {
+    'hash': 33004,
+    'name': 'Safe_Point',
+    'embedded': {
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {}
+      },
+      'Safe_Point_9078': {
+        'hash': 9078,
+        'name': 'Safe_Point',
+        'savables': {
+          'CheckPoint': {
+            'hash': 3704379512,
+            'name': 'CheckPoint'
+          },
+          'SafePositionSetter': {
+            'hash': 70871065,
+            'name': 'SafePositionSetter'
+          }
+        }
+      }
+    }
+  },
+  'Sai': {
+    'hash': 27038,
+    'name': 'Sai',
+    'embedded': {
+      'Sai_36330': {
+        'hash': 36330,
+        'name': 'Sai',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Salt': {
+    'hash': 49578,
+    'name': 'Salt',
+    'embedded': {
+      'Salt_30920': {
+        'hash': 30920,
+        'name': 'Salt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Sandstone_Boulder_01': {
+    'hash': 34168,
+    'name': 'Sandstone_Boulder_01',
+    'embedded': {
+      'Sandstone_Boulder_01_13178': {
+        'hash': 13178,
+        'name': 'Sandstone_Boulder_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Sandstone_Boulder_02': {
+    'hash': 8006,
+    'name': 'Sandstone_Boulder_02',
+    'embedded': {
+      'Sandstone_Boulder_02_13178': {
+        'hash': 13178,
+        'name': 'Sandstone_Boulder_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Sandstone_Boulder_03': {
+    'hash': 5050,
+    'name': 'Sandstone_Boulder_03',
+    'embedded': {
+      'Sandstone_Boulder_03_13178': {
+        'hash': 13178,
+        'name': 'Sandstone_Boulder_03',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Sandstone_Cluster': {
+    'hash': 41676,
+    'name': 'Sandstone_Cluster',
+    'embedded': {
+      'Sandstone_Cluster_41674': {
+        'hash': 41674,
+        'name': 'Sandstone_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Sandstone_Stone': {
+    'hash': 55930,
+    'name': 'Sandstone_Stone',
+    'embedded': {
+      'Sandstone_Stone_30920': {
+        'hash': 30920,
+        'name': 'Sandstone_Stone',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Sapling': {
+    'hash': 25994,
+    'name': 'Sapling',
+    'embedded': {
+      'Sapling_52900': {
+        'hash': 52900,
+        'name': 'Sapling',
+        'savables': {}
+      }
+    }
+  },
+  'Sapling_Freshly_Planted': {
+    'hash': 25992,
+    'name': 'Sapling_Freshly_Planted',
+    'embedded': {
+      'Sapling_Freshly_Planted_44026': {
+        'hash': 44026,
+        'name': 'Sapling_Freshly_Planted',
+        'savables': {}
+      }
+    }
+  },
+  'ScaleTemp': {
+    'hash': 64402,
+    'name': 'ScaleTemp',
+    'embedded': {}
+  },
+  'Schmeechee_Glowing': {
+    'hash': 53576,
+    'name': 'Schmeechee_Glowing',
+    'embedded': {
+      'Schmeechee_53578': {
+        'hash': 53578,
+        'name': 'Schmeechee',
+        'savables': {}
+      },
+      'Schmeechee_AI_58356': {
+        'hash': 58356,
+        'name': 'Schmeechee_AI',
+        'savables': {}
+      },
+      'Schmeechee_Glowing_53582': {
+        'hash': 53582,
+        'name': 'Schmeechee_Glowing',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Schmeechee_Orange': {
+    'hash': 63728,
+    'name': 'Schmeechee_Orange',
+    'embedded': {
+      'Schmeechee_21916': {
+        'hash': 21916,
+        'name': 'Schmeechee',
+        'savables': {}
+      },
+      'Schmeechee_AI_58356': {
+        'hash': 58356,
+        'name': 'Schmeechee_AI',
+        'savables': {}
+      },
+      'Schmeechee_Orange_58792': {
+        'hash': 58792,
+        'name': 'Schmeechee_Orange',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Schmeechee_Poisonous': {
+    'hash': 31646,
+    'name': 'Schmeechee_Poisonous',
+    'embedded': {
+      'Schmeechee_31648': {
+        'hash': 31648,
+        'name': 'Schmeechee',
+        'savables': {}
+      },
+      'Schmeechee_AI_58356': {
+        'hash': 58356,
+        'name': 'Schmeechee_AI',
+        'savables': {}
+      },
+      'Schmeechee_Poisonous_31652': {
+        'hash': 31652,
+        'name': 'Schmeechee_Poisonous',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Schmeechee_Red': {
+    'hash': 3532,
+    'name': 'Schmeechee_Red',
+    'embedded': {
+      'Schmeechee_3534': {
+        'hash': 3534,
+        'name': 'Schmeechee',
+        'savables': {}
+      },
+      'Schmeechee_AI_58356': {
+        'hash': 58356,
+        'name': 'Schmeechee_AI',
+        'savables': {}
+      },
+      'Schmeechee_Red_3538': {
+        'hash': 3538,
+        'name': 'Schmeechee_Red',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Scythe_Blade': {
+    'hash': 26788,
+    'name': 'Scythe_Blade',
+    'embedded': {
+      'Insert_AxeType_7796': {
+        'hash': 7796,
+        'name': 'Insert_AxeType',
+        'savables': {}
+      },
+      'Scythe_Blade_29280': {
+        'hash': 29280,
+        'name': 'Scythe_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'joint_blade_scythe_01_55756': {
+        'hash': 55756,
+        'name': 'joint_blade_scythe_01',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'joint_blade_scythe_02_55752': {
+        'hash': 55752,
+        'name': 'joint_blade_scythe_02',
+        'savables': {}
+      },
+      'joint_blade_scythe_03_55776': {
+        'hash': 55776,
+        'name': 'joint_blade_scythe_03',
+        'savables': {}
+      },
+      'joint_blade_scythe_04_55760': {
+        'hash': 55760,
+        'name': 'joint_blade_scythe_04',
+        'savables': {}
+      },
+      'joint_blade_scythe_05_55772': {
+        'hash': 55772,
+        'name': 'joint_blade_scythe_05',
+        'savables': {}
+      },
+      'joint_blade_scythe_06_55768': {
+        'hash': 55768,
+        'name': 'joint_blade_scythe_06',
+        'savables': {}
+      },
+      'joint_blade_scythe_07_55764': {
+        'hash': 55764,
+        'name': 'joint_blade_scythe_07',
+        'savables': {}
+      },
+      'metal_blade_scythe_full_geo_LOD0_2552': {
+        'hash': 2552,
+        'name': 'metal_blade_scythe_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Select_Server_Orb': {
+    'hash': 55760,
+    'name': 'Select_Server_Orb',
+    'embedded': {}
+  },
+  'Send_Post': {
+    'hash': 53190,
+    'name': 'Send_Post',
+    'embedded': {
+      'Grab_31026': {
+        'hash': 31026,
+        'name': 'Grab',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_5088': {
+        'hash': 5088,
+        'name': 'Handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Scroller_Touch_Mode_41098': {
+        'hash': 41098,
+        'name': 'Scroller_Touch_Mode',
+        'savables': {}
+      },
+      'Send_Post_53122': {
+        'hash': 53122,
+        'name': 'Send_Post',
+        'savables': {}
+      }
+    }
+  },
+  'Set_Piece': {
+    'hash': 62334,
+    'name': 'Set_Piece',
+    'embedded': {}
+  },
+  'Shelf': {
+    'hash': 23630,
+    'name': 'Shelf',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60210': {
+        'hash': 60210,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60212': {
+        'hash': 60212,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60214': {
+        'hash': 60214,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60216': {
+        'hash': 60216,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60218': {
+        'hash': 60218,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60220': {
+        'hash': 60220,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60222': {
+        'hash': 60222,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60224': {
+        'hash': 60224,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60226': {
+        'hash': 60226,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60228': {
+        'hash': 60228,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60230': {
+        'hash': 60230,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60232': {
+        'hash': 60232,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60234': {
+        'hash': 60234,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60236': {
+        'hash': 60236,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60238': {
+        'hash': 60238,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60240': {
+        'hash': 60240,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60242': {
+        'hash': 60242,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60244': {
+        'hash': 60244,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60246': {
+        'hash': 60246,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Shelf_5060': {
+        'hash': 5060,
+        'name': 'Shelf',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Shelf_Short': {
+    'hash': 20452,
+    'name': 'Shelf_Short',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58082': {
+        'hash': 58082,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58084': {
+        'hash': 58084,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58086': {
+        'hash': 58086,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58088': {
+        'hash': 58088,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58090': {
+        'hash': 58090,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58092': {
+        'hash': 58092,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58094': {
+        'hash': 58094,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58096': {
+        'hash': 58096,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_58098': {
+        'hash': 58098,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Shelf_Short_60158': {
+        'hash': 60158,
+        'name': 'Shelf_Short',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Shield': {
+    'hash': 61656,
+    'name': 'Shield',
+    'embedded': {
+      'Shield_32452': {
+        'hash': 32452,
+        'name': 'Shield',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Shield_Core_Bent_Middle': {
+    'hash': 7232,
+    'name': 'Shield_Core_Bent_Middle',
+    'embedded': {
+      'Insert_Shield_Handle_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Handle',
+        'savables': {}
+      },
+      'Shield_Core_Bent_Middle_10382': {
+        'hash': 10382,
+        'name': 'Shield_Core_Bent_Middle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Shield_Part_47874': {
+        'hash': 47874,
+        'name': 'Slot_Shield_Part',
+        'savables': {}
+      },
+      'Slot_Shield_Part_8898': {
+        'hash': 8898,
+        'name': 'Slot_Shield_Part',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Core_Circle_Middle': {
+    'hash': 52756,
+    'name': 'Shield_Core_Circle_Middle',
+    'embedded': {
+      'Insert_Shield_Handle_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Handle',
+        'savables': {}
+      },
+      'Shield_Core_Circle_Middle_52754': {
+        'hash': 52754,
+        'name': 'Shield_Core_Circle_Middle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Shield_Part_47874': {
+        'hash': 47874,
+        'name': 'Slot_Shield_Part',
+        'savables': {}
+      },
+      'Slot_Shield_Part_8898': {
+        'hash': 8898,
+        'name': 'Slot_Shield_Part',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Core_Handle': {
+    'hash': 4530,
+    'name': 'Shield_Core_Handle',
+    'embedded': {
+      'Shield_Core_Handle_4528': {
+        'hash': 4528,
+        'name': 'Shield_Core_Handle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Shield_Handle_47874': {
+        'hash': 47874,
+        'name': 'Slot_Shield_Handle',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Core_Holed_Middle': {
+    'hash': 50602,
+    'name': 'Shield_Core_Holed_Middle',
+    'embedded': {
+      'Insert_Shield_Handle_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Handle',
+        'savables': {}
+      },
+      'Shield_Core_Holed_Middle_50604': {
+        'hash': 50604,
+        'name': 'Shield_Core_Holed_Middle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Shield_Part_47874': {
+        'hash': 47874,
+        'name': 'Slot_Shield_Part',
+        'savables': {}
+      },
+      'Slot_Shield_Part_8898': {
+        'hash': 8898,
+        'name': 'Slot_Shield_Part',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Part_Half_Circle': {
+    'hash': 50888,
+    'name': 'Shield_Part_Half_Circle',
+    'embedded': {
+      'Insert_Shield_Part_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Part',
+        'savables': {}
+      },
+      'Shield_Part_Half_Circle_50886': {
+        'hash': 50886,
+        'name': 'Shield_Part_Half_Circle',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Deco_25868': {
+        'hash': 25868,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_25870': {
+        'hash': 25870,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_51506': {
+        'hash': 51506,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_51508': {
+        'hash': 51508,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_52564': {
+        'hash': 52564,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_52566': {
+        'hash': 52566,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_53718': {
+        'hash': 53718,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_53720': {
+        'hash': 53720,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_55242': {
+        'hash': 55242,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_55244': {
+        'hash': 55244,
+        'name': 'Slot_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Part_Half_Circle_Hole': {
+    'hash': 44704,
+    'name': 'Shield_Part_Half_Circle_Hole',
+    'embedded': {
+      'Insert_Shield_Part_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Part',
+        'savables': {}
+      },
+      'Shield_Part_Half_Circle_Hole_44702': {
+        'hash': 44702,
+        'name': 'Shield_Part_Half_Circle_Hole',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Deco_25868': {
+        'hash': 25868,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_25870': {
+        'hash': 25870,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_51506': {
+        'hash': 51506,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_51508': {
+        'hash': 51508,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_52564': {
+        'hash': 52564,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_52566': {
+        'hash': 52566,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_55242': {
+        'hash': 55242,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_55244': {
+        'hash': 55244,
+        'name': 'Slot_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Part_Half_Hole': {
+    'hash': 12416,
+    'name': 'Shield_Part_Half_Hole',
+    'embedded': {
+      'Insert_Shield_Part_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Part',
+        'savables': {}
+      },
+      'Shield_Part_Half_Hole_12414': {
+        'hash': 12414,
+        'name': 'Shield_Part_Half_Hole',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Deco_20018': {
+        'hash': 20018,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_46580': {
+        'hash': 46580,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_52138': {
+        'hash': 52138,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_56752': {
+        'hash': 56752,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_63256': {
+        'hash': 63256,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_854': {
+        'hash': 854,
+        'name': 'Slot_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Shield_Part_Half_Point_01': {
+    'hash': 59936,
+    'name': 'Shield_Part_Half_Point_01',
+    'embedded': {
+      'Insert_Shield_Part_112': {
+        'hash': 112,
+        'name': 'Insert_Shield_Part',
+        'savables': {}
+      },
+      'Shield_Part_Half_Point_01_56662': {
+        'hash': 56662,
+        'name': 'Shield_Part_Half_Point_01',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Slot_Deco_20420': {
+        'hash': 20420,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_26340': {
+        'hash': 26340,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_26366': {
+        'hash': 26366,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_26368': {
+        'hash': 26368,
+        'name': 'Slot_Deco',
+        'savables': {}
+      },
+      'Slot_Deco_26396': {
+        'hash': 26396,
+        'name': 'Slot_Deco',
+        'savables': {}
+      }
+    }
+  },
+  'Short_Sword': {
+    'hash': 38566,
+    'name': 'Short_Sword',
+    'embedded': {
+      'Short_Sword_36330': {
+        'hash': 36330,
+        'name': 'Short_Sword',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Short_Sword_Blade': {
+    'hash': 55310,
+    'name': 'Short_Sword_Blade',
+    'embedded': {
+      'Heat_Point_Collection_63534': {
+        'hash': 63534,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Straight_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Straight_SwordType',
+        'savables': {}
+      },
+      'Short_Sword_Blade_36330': {
+        'hash': 36330,
+        'name': 'Short_Sword_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'metal_blade_shortSword_full_geo_LOD0_4044': {
+        'hash': 4044,
+        'name': 'metal_blade_shortSword_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Short_Sword_Training': {
+    'hash': 1150,
+    'name': 'Short_Sword_Training',
+    'embedded': {
+      'Short_Sword_Training_1152': {
+        'hash': 1152,
+        'name': 'Short_Sword_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Shotel_Blade': {
+    'hash': 36438,
+    'name': 'Shotel_Blade',
+    'embedded': {
+      'Heat_Point_Collection_2136': {
+        'hash': 2136,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_SwordType',
+        'savables': {}
+      },
+      'Shotel_Blade_36346': {
+        'hash': 36346,
+        'name': 'Shotel_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'metal_blade_shotel_full_geo_LOD0_22394': {
+        'hash': 22394,
+        'name': 'metal_blade_shotel_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Silver_Boulder': {
+    'hash': 9144,
+    'name': 'Silver_Boulder',
+    'embedded': {
+      'Silver_Boulder_11186': {
+        'hash': 11186,
+        'name': 'Silver_Boulder',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawn_Origin_50402': {
+        'hash': 50402,
+        'name': 'Spawn_Origin',
+        'savables': {}
+      }
+    }
+  },
+  'Silver_Boulder_Parts': {
+    'hash': 17120,
+    'name': 'Silver_Boulder_Parts',
+    'embedded': {
+      'Silver_Boulder_Parts_56732': {
+        'hash': 56732,
+        'name': 'Silver_Boulder_Parts',
+        'savables': {}
+      },
+      'Silver_Boulder_part_01_56744': {
+        'hash': 56744,
+        'name': 'Silver_Boulder_part_01',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Silver_Boulder_part_02_56752': {
+        'hash': 56752,
+        'name': 'Silver_Boulder_part_02',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Silver_Boulder_part_03_56748': {
+        'hash': 56748,
+        'name': 'Silver_Boulder_part_03',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Silver_Ingot': {
+    'hash': 23528,
+    'name': 'Silver_Ingot',
+    'embedded': {
+      'Heat_Point_Collection_13678': {
+        'hash': 13678,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Silver_Ingot_23416': {
+        'hash': 23416,
+        'name': 'Silver_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Silver_Ore': {
+    'hash': 9586,
+    'name': 'Silver_Ore',
+    'embedded': {
+      'Silver_Ore_28602': {
+        'hash': 28602,
+        'name': 'Silver_Ore',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Skill_Orb': {
+    'hash': 17270,
+    'name': 'Skill_Orb',
+    'embedded': {
+      'Skill_Orb_35828': {
+        'hash': 35828,
+        'name': 'Skill_Orb',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Skill_Orb_Replacer': {
+    'hash': 23526,
+    'name': 'Skill_Orb_Replacer',
+    'embedded': {
+      'Skill_Orb_Replacer_35828': {
+        'hash': 35828,
+        'name': 'Skill_Orb_Replacer',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'SlidingBlockTestLayoutINCOMPLETE': {
+    'hash': 8280,
+    'name': 'SlidingBlockTestLayoutINCOMPLETE',
+    'embedded': {}
+  },
+  'Sliding_Door': {
+    'hash': 33420,
+    'name': 'Sliding_Door',
+    'embedded': {}
+  },
+  'Slingshot': {
+    'hash': 13142,
+    'name': 'Slingshot',
+    'embedded': {
+      'Projectile_Dock_40686': {
+        'hash': 40686,
+        'name': 'Projectile_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Slingshot_15402': {
+        'hash': 15402,
+        'name': 'Slingshot',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'String_40688': {
+        'hash': 40688,
+        'name': 'String',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Slow_Grass': {
+    'hash': 59062,
+    'name': 'Slow_Grass',
+    'embedded': {
+      'Slow_Grass_7970': {
+        'hash': 7970,
+        'name': 'Slow_Grass',
+        'savables': {}
+      }
+    }
+  },
+  'Small_Bone_Spike': {
+    'hash': 61488,
+    'name': 'Small_Bone_Spike',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Small_Bone_Spike_15532': {
+        'hash': 15532,
+        'name': 'Small_Bone_Spike',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Small_Cave_Mushroom_01': {
+    'hash': 33796,
+    'name': 'Small_Cave_Mushroom_01',
+    'embedded': {
+      'Small_Cave_Mushroom_01_33544': {
+        'hash': 33544,
+        'name': 'Small_Cave_Mushroom_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawner_3488': {
+        'hash': 3488,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'cave_mushroom_small_spineTop_jnt_38718': {
+        'hash': 38718,
+        'name': 'cave_mushroom_small_spineTop_jnt',
+        'savables': {}
+      },
+      'cave_mushroom_small_spine_jnt_46098': {
+        'hash': 46098,
+        'name': 'cave_mushroom_small_spine_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Small_Cave_Mushroom_Cluster': {
+    'hash': 56444,
+    'name': 'Small_Cave_Mushroom_Cluster',
+    'embedded': {
+      'Small_Cave_Mushroom_Cluster_61380': {
+        'hash': 61380,
+        'name': 'Small_Cave_Mushroom_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Small_Shield': {
+    'hash': 63498,
+    'name': 'Small_Shield',
+    'embedded': {
+      'Insert_Shield_64244': {
+        'hash': 64244,
+        'name': 'Insert_Shield',
+        'savables': {}
+      },
+      'Small_Shield_32452': {
+        'hash': 32452,
+        'name': 'Small_Shield',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Small_Shield_Training': {
+    'hash': 21312,
+    'name': 'Small_Shield_Training',
+    'embedded': {
+      'Small_Shield_Training_21302': {
+        'hash': 21302,
+        'name': 'Small_Shield_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Smelter': {
+    'hash': 44646,
+    'name': 'Smelter',
+    'embedded': {
+      'Dock_37092': {
+        'hash': 37092,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_37150': {
+        'hash': 37150,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_37236': {
+        'hash': 37236,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Fuel_54958': {
+        'hash': 54958,
+        'name': 'Dock_Fuel',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Ore_(B)_42990': {
+        'hash': 42990,
+        'name': 'Dock_Ore_(B)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Ore_(T)_54962': {
+        'hash': 54962,
+        'name': 'Dock_Ore_(T)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Ore_Dispenser_L_54940': {
+        'hash': 54940,
+        'name': 'Dock_Ore_Dispenser_L',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Ore_Dispenser_M_54938': {
+        'hash': 54938,
+        'name': 'Dock_Ore_Dispenser_M',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Ore_Dispenser_R_54936': {
+        'hash': 54936,
+        'name': 'Dock_Ore_Dispenser_R',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Output_54928': {
+        'hash': 54928,
+        'name': 'Dock_Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_Output_54930': {
+        'hash': 54930,
+        'name': 'Dock_Output',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Fire_54948': {
+        'hash': 54948,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          }
+        }
+      },
+      'Handle_24422': {
+        'hash': 24422,
+        'name': 'Handle',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_38408': {
+        'hash': 38408,
+        'name': 'Handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_5088': {
+        'hash': 5088,
+        'name': 'Handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Mould_Dock_54960': {
+        'hash': 54960,
+        'name': 'Mould_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Smelter_19322': {
+        'hash': 19322,
+        'name': 'Smelter',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'Smelter': {
+            'hash': 902024186,
+            'name': 'Smelter'
+          }
+        }
+      },
+      'UnlockDocks_10172': {
+        'hash': 10172,
+        'name': 'UnlockDocks',
+        'savables': {
+          'PositionRestrictor': {
+            'hash': 1776498660,
+            'name': 'PositionRestrictor'
+          }
+        }
+      },
+      'smelter_bellows_arm_jnt_25672': {
+        'hash': 25672,
+        'name': 'smelter_bellows_arm_jnt',
+        'savables': {}
+      },
+      'smelter_dispenser_lever_Handle_5912': {
+        'hash': 5912,
+        'name': 'smelter_dispenser_lever_Handle',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'smelter_fuelGate_handle_59832': {
+        'hash': 59832,
+        'name': 'smelter_fuelGate_handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'smelter_fuelGate_pivot_10060': {
+        'hash': 10060,
+        'name': 'smelter_fuelGate_pivot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Smelter_Gem_1': {
+    'hash': 34986,
+    'name': 'Smelter_Gem_1',
+    'embedded': {
+      'Smelter_Gem_1_11514': {
+        'hash': 11514,
+        'name': 'Smelter_Gem_1',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Smelter_Gem_2': {
+    'hash': 41638,
+    'name': 'Smelter_Gem_2',
+    'embedded': {
+      'Smelter_Gem_2_11514': {
+        'hash': 11514,
+        'name': 'Smelter_Gem_2',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Smelter_Gem_3': {
+    'hash': 46508,
+    'name': 'Smelter_Gem_3',
+    'embedded': {
+      'Smelter_Gem_3_11514': {
+        'hash': 11514,
+        'name': 'Smelter_Gem_3',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Smelter_gem_2_item_pedestal': {
+    'hash': 56098,
+    'name': 'Smelter_gem_2_item_pedestal',
+    'embedded': {
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      },
+      'Smelter_gem_2_item_pedestal_27194': {
+        'hash': 27194,
+        'name': 'Smelter_gem_2_item_pedestal',
+        'savables': {}
+      }
+    }
+  },
+  'Smelter_gem_3_item_pedestal': {
+    'hash': 63036,
+    'name': 'Smelter_gem_3_item_pedestal',
+    'embedded': {
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      },
+      'Smelter_gem_3_item_pedestal_27194': {
+        'hash': 27194,
+        'name': 'Smelter_gem_3_item_pedestal',
+        'savables': {}
+      }
+    }
+  },
+  'SnowballMoundSpawner': {
+    'hash': 30542,
+    'name': 'SnowballMoundSpawner',
+    'embedded': {
+      'SnowballMoundSpawner_24412': {
+        'hash': 24412,
+        'name': 'SnowballMoundSpawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'SnowballSpawner': {
+    'hash': 22418,
+    'name': 'SnowballSpawner',
+    'embedded': {
+      'SnowballSpawner_52610': {
+        'hash': 52610,
+        'name': 'SnowballSpawner',
+        'savables': {}
+      },
+      'Spawner_528': {
+        'hash': 528,
+        'name': 'Spawner',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'SpawnInCircle': {
+            'hash': 1714180166,
+            'name': 'SpawnInCircle'
+          }
+        }
+      }
+    }
+  },
+  'Snowball_network_Prefab': {
+    'hash': 52090,
+    'name': 'Snowball_network_Prefab',
+    'embedded': {
+      'Snowball_network_Prefab_36924': {
+        'hash': 36924,
+        'name': 'Snowball_network_Prefab',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Snowman_Network_Prefab_1': {
+    'hash': 57830,
+    'name': 'Snowman_Network_Prefab_1',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Snowman_Network_Prefab_1_25600': {
+        'hash': 25600,
+        'name': 'Snowman_Network_Prefab_1',
+        'savables': {}
+      }
+    }
+  },
+  'Snowman_Network_Prefab_2': {
+    'hash': 16878,
+    'name': 'Snowman_Network_Prefab_2',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Snowman_Network_Prefab_2_25600': {
+        'hash': 25600,
+        'name': 'Snowman_Network_Prefab_2',
+        'savables': {}
+      }
+    }
+  },
+  'Snowman_Network_Prefab_3': {
+    'hash': 17612,
+    'name': 'Snowman_Network_Prefab_3',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Snowman_Network_Prefab_3_25600': {
+        'hash': 25600,
+        'name': 'Snowman_Network_Prefab_3',
+        'savables': {}
+      }
+    }
+  },
+  'Snowman_Network_Prefab_test': {
+    'hash': 25690,
+    'name': 'Snowman_Network_Prefab_test',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Snowman_Network_Prefab_test_25600': {
+        'hash': 25600,
+        'name': 'Snowman_Network_Prefab_test',
+        'savables': {}
+      }
+    }
+  },
+  'Soft_Fabric_Large_Roll': {
+    'hash': 23206,
+    'name': 'Soft_Fabric_Large_Roll',
+    'embedded': {
+      'Soft_Fabric_Large_Roll_47776': {
+        'hash': 47776,
+        'name': 'Soft_Fabric_Large_Roll',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawner_43650': {
+        'hash': 43650,
+        'name': 'Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Soft_Fabric_Medium_Roll': {
+    'hash': 47760,
+    'name': 'Soft_Fabric_Medium_Roll',
+    'embedded': {
+      'Soft_Fabric_Medium_Roll_47776': {
+        'hash': 47776,
+        'name': 'Soft_Fabric_Medium_Roll',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spawner_43650': {
+        'hash': 43650,
+        'name': 'Spawner',
+        'savables': {}
+      }
+    }
+  },
+  'Soft_Fabric_Medium_Strips': {
+    'hash': 63204,
+    'name': 'Soft_Fabric_Medium_Strips',
+    'embedded': {
+      'Soft_Fabric_Medium_Strips_63188': {
+        'hash': 63188,
+        'name': 'Soft_Fabric_Medium_Strips',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Spade_Head': {
+    'hash': 50548,
+    'name': 'Spade_Head',
+    'embedded': {
+      'Fake_Pickup_6096': {
+        'hash': 6096,
+        'name': 'Fake_Pickup',
+        'savables': {}
+      },
+      'Insert_AxeType_7796': {
+        'hash': 7796,
+        'name': 'Insert_AxeType',
+        'savables': {}
+      },
+      'Spade_Head_60654': {
+        'hash': 60654,
+        'name': 'Spade_Head',
+        'savables': {
+          'DiggingImpactor': {
+            'hash': 3445325106,
+            'name': 'DiggingImpactor'
+          },
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'spade_head_LOD0_45520': {
+        'hash': 45520,
+        'name': 'spade_head_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Spawn_Point': {
+    'hash': 63844,
+    'name': 'Spawn_Point',
+    'embedded': {
+      'Spawn_Point_4036': {
+        'hash': 4036,
+        'name': 'Spawn_Point',
+        'savables': {}
+      }
+    }
+  },
+  'Spawner_Test': {
+    'hash': 51070,
+    'name': 'Spawner_Test',
+    'embedded': {}
+  },
+  'Spear_Head_Pyramid': {
+    'hash': 13554,
+    'name': 'Spear_Head_Pyramid',
+    'embedded': {}
+  },
+  'Spear_Head_Spiky': {
+    'hash': 13680,
+    'name': 'Spear_Head_Spiky',
+    'embedded': {}
+  },
+  'Spear_Head_Standard': {
+    'hash': 13816,
+    'name': 'Spear_Head_Standard',
+    'embedded': {}
+  },
+  'Spectral_Ghost': {
+    'hash': 57494,
+    'name': 'Spectral_Ghost',
+    'embedded': {}
+  },
+  'Spherical_Encounter': {
+    'hash': 1222,
+    'name': 'Spherical_Encounter',
+    'embedded': {
+      /** @todo Verify entities and their components. */
+      'Spherical_Encounter_43896': {
+        'hash': 43896,
+        'name': 'Spherical_Encounter',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Spike_Fancy': {
+    'hash': 12492,
+    'name': 'Spike_Fancy',
+    'embedded': {
+      'Heat_Point_Collection_3584': {
+        'hash': 3584,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Spike_Fancy_15532': {
+        'hash': 15532,
+        'name': 'Spike_Fancy',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spike_Short': {
+    'hash': 6934,
+    'name': 'Spike_Short',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Spike_Short_15532': {
+        'hash': 15532,
+        'name': 'Spike_Short',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spike_Tall': {
+    'hash': 3558,
+    'name': 'Spike_Tall',
+    'embedded': {
+      'Insert_Deco_112': {
+        'hash': 112,
+        'name': 'Insert_Deco',
+        'savables': {}
+      },
+      'Spike_Tall_15532': {
+        'hash': 15532,
+        'name': 'Spike_Tall',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spire_Gcore_Dynamic': {
+    'hash': 23472,
+    'name': 'Spire_Gcore_Dynamic',
+    'embedded': {
+      'Directional_Encounter_33516': {
+        'hash': 33516,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Spire_Gcore_Dynamic_23456': {
+        'hash': 23456,
+        'name': 'Spire_Gcore_Dynamic',
+        'savables': {}
+      }
+    }
+  },
+  'Spread_Spawner_Dynamic': {
+    'hash': 18426,
+    'name': 'Spread_Spawner_Dynamic',
+    'embedded': {
+      'Directional_Encounter_(1)_45120': {
+        'hash': 45120,
+        'name': 'Directional_Encounter_(1)',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Directional_Encounter_45108': {
+        'hash': 45108,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Spread_Spawner_Dynamic_18410': {
+        'hash': 18410,
+        'name': 'Spread_Spawner_Dynamic',
+        'savables': {}
+      }
+    }
+  },
+  'Spriggull': {
+    'hash': 62050,
+    'name': 'Spriggull',
+    'embedded': {
+      'Body_60576': {
+        'hash': 60576,
+        'name': 'Body',
+        'savables': {}
+      },
+      'Heat_42194': {
+        'hash': 42194,
+        'name': 'Heat',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Interactor_2642': {
+        'hash': 2642,
+        'name': 'Interactor',
+        'savables': {}
+      },
+      'Spriggull_62666': {
+        'hash': 62666,
+        'name': 'Spriggull',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Spriggull_AI_58356': {
+        'hash': 58356,
+        'name': 'Spriggull_AI',
+        'savables': {}
+      },
+      'skin_jaw_jnt_48650': {
+        'hash': 48650,
+        'name': 'skin_jaw_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'SpriggullDrumstick_Bone': {
+    'hash': 24406,
+    'name': 'SpriggullDrumstick_Bone',
+    'embedded': {
+      'SpriggullDrumstick_Bone_26390': {
+        'hash': 26390,
+        'name': 'SpriggullDrumstick_Bone',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'SpriggullDrumstick_Full_Burnt': {
+    'hash': 20570,
+    'name': 'SpriggullDrumstick_Full_Burnt',
+    'embedded': {
+      'Bone_Spawner_16064': {
+        'hash': 16064,
+        'name': 'Bone_Spawner',
+        'savables': {}
+      },
+      'Cooking_35958': {
+        'hash': 35958,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'SpriggullDrumstick_Full_Burnt_36708': {
+        'hash': 36708,
+        'name': 'SpriggullDrumstick_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'SpriggullDrumstick_Full_Cooked': {
+    'hash': 33190,
+    'name': 'SpriggullDrumstick_Full_Cooked',
+    'embedded': {
+      'Bone_Spawner_16556': {
+        'hash': 16556,
+        'name': 'Bone_Spawner',
+        'savables': {}
+      },
+      'Cooking_29822': {
+        'hash': 29822,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'SpriggullDrumstick_Full_Cooked_30572': {
+        'hash': 30572,
+        'name': 'SpriggullDrumstick_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'SpriggullDrumstick_Full_Ripe': {
+    'hash': 43430,
+    'name': 'SpriggullDrumstick_Full_Ripe',
+    'embedded': {
+      'Bone_Spawner_38786': {
+        'hash': 38786,
+        'name': 'Bone_Spawner',
+        'savables': {}
+      },
+      'Cooking_24500': {
+        'hash': 24500,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'SpriggullDrumstick_Full_Ripe_25250': {
+        'hash': 25250,
+        'name': 'SpriggullDrumstick_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'SpriggullDrumstick_Half_Burnt': {
+    'hash': 10908,
+    'name': 'SpriggullDrumstick_Half_Burnt',
+    'embedded': {
+      'Cooking_19872': {
+        'hash': 19872,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'SpriggullDrumstick_Half_Burnt_19928': {
+        'hash': 19928,
+        'name': 'SpriggullDrumstick_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'SpriggullDrumstick_Half_Cooked': {
+    'hash': 8440,
+    'name': 'SpriggullDrumstick_Half_Cooked',
+    'embedded': {
+      'Cooking_18026': {
+        'hash': 18026,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'SpriggullDrumstick_Half_Cooked_18082': {
+        'hash': 18082,
+        'name': 'SpriggullDrumstick_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'SpriggullDrumstick_Half_Ripe': {
+    'hash': 5972,
+    'name': 'SpriggullDrumstick_Half_Ripe',
+    'embedded': {
+      'Cooking_16182': {
+        'hash': 16182,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'SpriggullDrumstick_Half_Ripe_16238': {
+        'hash': 16238,
+        'name': 'SpriggullDrumstick_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Egg': {
+    'hash': 7014,
+    'name': 'Spriggull_Egg',
+    'embedded': {
+      'Spriggull_Egg_5216': {
+        'hash': 5216,
+        'name': 'Spriggull_Egg',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Feather_Blue': {
+    'hash': 7918,
+    'name': 'Spriggull_Feather_Blue',
+    'embedded': {
+      'Spriggull_Feather_Blue_61684': {
+        'hash': 61684,
+        'name': 'Spriggull_Feather_Blue',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Feather_Green': {
+    'hash': 25446,
+    'name': 'Spriggull_Feather_Green',
+    'embedded': {
+      'Insert_Feather_112': {
+        'hash': 112,
+        'name': 'Insert_Feather',
+        'savables': {}
+      },
+      'Spriggull_Feather_Green_25450': {
+        'hash': 25450,
+        'name': 'Spriggull_Feather_Green',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Feather_Purple': {
+    'hash': 36248,
+    'name': 'Spriggull_Feather_Purple',
+    'embedded': {
+      'Insert_Feather_112': {
+        'hash': 112,
+        'name': 'Insert_Feather',
+        'savables': {}
+      },
+      'Spriggull_Feather_Purple_36244': {
+        'hash': 36244,
+        'name': 'Spriggull_Feather_Purple',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Feather_Red': {
+    'hash': 18734,
+    'name': 'Spriggull_Feather_Red',
+    'embedded': {
+      'Spriggull_Feather_Red_18738': {
+        'hash': 18738,
+        'name': 'Spriggull_Feather_Red',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Fletching_Blue': {
+    'hash': 50608,
+    'name': 'Spriggull_Fletching_Blue',
+    'embedded': {
+      'Insert_Feather_51282': {
+        'hash': 51282,
+        'name': 'Insert_Feather',
+        'savables': {}
+      },
+      'Spriggull_Fletching_Blue_51284': {
+        'hash': 51284,
+        'name': 'Spriggull_Fletching_Blue',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Fletching_Red': {
+    'hash': 24072,
+    'name': 'Spriggull_Fletching_Red',
+    'embedded': {
+      'Insert_Feather_112': {
+        'hash': 112,
+        'name': 'Insert_Feather',
+        'savables': {}
+      },
+      'Spriggull_Fletching_Red_18738': {
+        'hash': 18738,
+        'name': 'Spriggull_Fletching_Red',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Spriggull_Nest': {
+    'hash': 16680,
+    'name': 'Spriggull_Nest',
+    'embedded': {
+      'Spriggull_Nest_16166': {
+        'hash': 16166,
+        'name': 'Spriggull_Nest',
+        'savables': {}
+      }
+    }
+  },
+  'SpyGlass': {
+    'hash': 5170,
+    'name': 'SpyGlass',
+    'embedded': {
+      'SpyGlass_7714': {
+        'hash': 7714,
+        'name': 'SpyGlass',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'spyglass_body_01_57858': {
+        'hash': 57858,
+        'name': 'spyglass_body_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'spyglass_body_02_57854': {
+        'hash': 57854,
+        'name': 'spyglass_body_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'spyglass_wraps_57850': {
+        'hash': 57850,
+        'name': 'spyglass_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'SpyGlass_Long': {
+    'hash': 64848,
+    'name': 'SpyGlass_Long',
+    'embedded': {
+      'SpyGlass_Long_7714': {
+        'hash': 7714,
+        'name': 'SpyGlass_Long',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Stalactite_pillar': {
+    'hash': 3944,
+    'name': 'Stalactite_pillar',
+    'embedded': {
+      'Explosion_17130': {
+        'hash': 17130,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosion_17244': {
+        'hash': 17244,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosion_17358': {
+        'hash': 17358,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosion_17472': {
+        'hash': 17472,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosion_17586': {
+        'hash': 17586,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosion_17700': {
+        'hash': 17700,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosion_21698': {
+        'hash': 21698,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_17234': {
+        'hash': 17234,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_17348': {
+        'hash': 17348,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_17462': {
+        'hash': 17462,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_17576': {
+        'hash': 17576,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_17690': {
+        'hash': 17690,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_17804': {
+        'hash': 17804,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Explosive_Spike_Stalactite(NoNetworkPrefab)_21742': {
+        'hash': 21742,
+        'name': 'Explosive_Spike_Stalactite(NoNetworkPrefab)',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'Hit_Detection_44554': {
+        'hash': 44554,
+        'name': 'Hit_Detection',
+        'savables': {
+          'ImpactDetectionLogic': {
+            'hash': 1435171891,
+            'name': 'ImpactDetectionLogic'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Stalactite_pillar_50810': {
+        'hash': 50810,
+        'name': 'Stalactite_pillar',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      }
+    }
+  },
+  'Standard_Crafted_Mould': {
+    'hash': 38578,
+    'name': 'Standard_Crafted_Mould',
+    'embedded': {
+      'Flat_Mould_Emblem_9986': {
+        'hash': 9986,
+        'name': 'Flat_Mould_Emblem',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Standard_Crafted_Mould_14710': {
+        'hash': 14710,
+        'name': 'Standard_Crafted_Mould',
+        'savables': {
+          'Mould': {
+            'hash': 391977879,
+            'name': 'Mould'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'mould_standard_ingotGraphic_60818': {
+        'hash': 60818,
+        'name': 'mould_standard_ingotGraphic',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'mould_standard_outerFrame_01_60826': {
+        'hash': 60826,
+        'name': 'mould_standard_outerFrame_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'mould_standard_railSlot_01_60830': {
+        'hash': 60830,
+        'name': 'mould_standard_railSlot_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'mould_standard_railSlot_02_60814': {
+        'hash': 60814,
+        'name': 'mould_standard_railSlot_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'mould_standard_railSlot_03_60822': {
+        'hash': 60822,
+        'name': 'mould_standard_railSlot_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'mould_standard_railSlot_04_60806': {
+        'hash': 60806,
+        'name': 'mould_standard_railSlot_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'mould_standard_timesGraphic_60810': {
+        'hash': 60810,
+        'name': 'mould_standard_timesGraphic',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Standard_Side_Pouch_Attachment': {
+    'hash': 7852,
+    'name': 'Standard_Side_Pouch_Attachment',
+    'embedded': {
+      'Dock_45700': {
+        'hash': 45700,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Insert_Bag_Attach_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Attach',
+        'savables': {}
+      },
+      'Standard_Side_Pouch_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Standard_Side_Pouch_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Storage_52822': {
+        'hash': 52822,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'standard_sidePouch_backPin_L1_7968': {
+        'hash': 7968,
+        'name': 'standard_sidePouch_backPin_L1',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_sidePouch_body_7972': {
+        'hash': 7972,
+        'name': 'standard_sidePouch_body',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_sidePouch_body_flap_7980': {
+        'hash': 7980,
+        'name': 'standard_sidePouch_body_flap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_sidePouch_flap_7976': {
+        'hash': 7976,
+        'name': 'standard_sidePouch_flap',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Standard_Side_Tool_Attachment': {
+    'hash': 59468,
+    'name': 'Standard_Side_Tool_Attachment',
+    'embedded': {
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'AdditionalOwnedDock': {
+            'hash': 2592242915,
+            'name': 'AdditionalOwnedDock'
+          }
+        }
+      },
+      'Insert_Bag_Attach_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Attach',
+        'savables': {}
+      },
+      'Standard_Side_Tool_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Standard_Side_Tool_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Storage_52526': {
+        'hash': 52526,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'standard_sideTool_slot_loop_33788': {
+        'hash': 33788,
+        'name': 'standard_sideTool_slot_loop',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_sideTool_slot_pad_01_33784': {
+        'hash': 33784,
+        'name': 'standard_sideTool_slot_pad_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_sideTool_slot_pad_02_33780': {
+        'hash': 33780,
+        'name': 'standard_sideTool_slot_pad_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'standard_sideTool_slot_strap_01_33776': {
+        'hash': 33776,
+        'name': 'standard_sideTool_slot_strap_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Standard_Stages': {
+    'hash': 31152,
+    'name': 'Standard_Stages',
+    'embedded': {
+      'Standard_Stages_53224': {
+        'hash': 53224,
+        'name': 'Standard_Stages',
+        'savables': {
+          'StageBasedPrefab': {
+            'hash': 1390862571,
+            'name': 'StageBasedPrefab'
+          }
+        }
+      }
+    }
+  },
+  'Steam_Spray': {
+    'hash': 53376,
+    'name': 'Steam_Spray',
+    'embedded': {
+      'Hurting_Bit_26178': {
+        'hash': 26178,
+        'name': 'Hurting_Bit',
+        'savables': {}
+      },
+      'Start_event_44764': {
+        'hash': 44764,
+        'name': 'Start_event',
+        'savables': {}
+      },
+      'Steam_Spray_61896': {
+        'hash': 61896,
+        'name': 'Steam_Spray',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'Stop_event_45050': {
+        'hash': 45050,
+        'name': 'Stop_event',
+        'savables': {}
+      }
+    }
+  },
+  'Steel_Alloy_Ingot': {
+    'hash': 22222,
+    'name': 'Steel_Alloy_Ingot',
+    'embedded': {}
+  },
+  'Stick': {
+    'hash': 61674,
+    'name': 'Stick',
+    'embedded': {
+      'Slot_Multi_64914': {
+        'hash': 64914,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Slot_Primitive_SwordType_30294': {
+        'hash': 30294,
+        'name': 'Slot_Primitive_SwordType',
+        'savables': {}
+      },
+      'Stick_31654': {
+        'hash': 31654,
+        'name': 'Stick',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Stick_Charred': {
+    'hash': 20564,
+    'name': 'Stick_Charred',
+    'embedded': {
+      'Stick_Charred_31654': {
+        'hash': 31654,
+        'name': 'Stick_Charred',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Stick_Storage': {
+    'hash': 46252,
+    'name': 'Stick_Storage',
+    'embedded': {
+      'Filter_Dock_57214': {
+        'hash': 57214,
+        'name': 'Filter_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Interaction_Point_59032': {
+        'hash': 59032,
+        'name': 'Interaction_Point',
+        'savables': {}
+      },
+      'Internal_Dock_59328': {
+        'hash': 59328,
+        'name': 'Internal_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Stick_Storage_59042': {
+        'hash': 59042,
+        'name': 'Stick_Storage',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'CommunalStorage': {
+            'hash': 3084373371,
+            'name': 'CommunalStorage'
+          },
+          'PlayerInteractionRestrictor': {
+            'hash': 2951515968,
+            'name': 'PlayerInteractionRestrictor'
+          }
+        }
+      },
+      'Withdraw_Dock_34750': {
+        'hash': 34750,
+        'name': 'Withdraw_Dock',
+        'savables': {}
+      }
+    }
+  },
+  'Stick_Training': {
+    'hash': 61414,
+    'name': 'Stick_Training',
+    'embedded': {
+      'Stick_Training_61396': {
+        'hash': 61396,
+        'name': 'Stick_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Stone': {
+    'hash': 61670,
+    'name': 'Stone',
+    'embedded': {
+      'Insert_Primitive_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Primitive_SwordType',
+        'savables': {}
+      },
+      'Stone_30920': {
+        'hash': 30920,
+        'name': 'Stone',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Stone_Boulder_01': {
+    'hash': 33376,
+    'name': 'Stone_Boulder_01',
+    'embedded': {
+      'Stone_Boulder_01_33370': {
+        'hash': 33370,
+        'name': 'Stone_Boulder_01',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Stone_Boulder_02': {
+    'hash': 17686,
+    'name': 'Stone_Boulder_02',
+    'embedded': {
+      'Stone_Boulder_02_17680': {
+        'hash': 17680,
+        'name': 'Stone_Boulder_02',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Stone_Boulder_03': {
+    'hash': 12450,
+    'name': 'Stone_Boulder_03',
+    'embedded': {
+      'Stone_Boulder_03_12444': {
+        'hash': 12444,
+        'name': 'Stone_Boulder_03',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Stone_Boulder_Cluster': {
+    'hash': 8948,
+    'name': 'Stone_Boulder_Cluster',
+    'embedded': {
+      'Stone_Boulder_Cluster_8942': {
+        'hash': 8942,
+        'name': 'Stone_Boulder_Cluster',
+        'savables': {}
+      }
+    }
+  },
+  'Stone_Training': {
+    'hash': 19490,
+    'name': 'Stone_Training',
+    'embedded': {
+      'Stone_Training_19480': {
+        'hash': 19480,
+        'name': 'Stone_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Storage_Chest': {
+    'hash': 63826,
+    'name': 'Storage_Chest',
+    'embedded': {
+      'Bottom_Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Bottom_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_2_2778': {
+        'hash': 2778,
+        'name': 'Bottom_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_3_2776': {
+        'hash': 2776,
+        'name': 'Bottom_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_4_2770': {
+        'hash': 2770,
+        'name': 'Bottom_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_5_2772': {
+        'hash': 2772,
+        'name': 'Bottom_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_6_2774': {
+        'hash': 2774,
+        'name': 'Bottom_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Left_23970': {
+        'hash': 23970,
+        'name': 'Handle_Left',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_Right_23964': {
+        'hash': 23964,
+        'name': 'Handle_Right',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Lid_2768': {
+        'hash': 2768,
+        'name': 'Lid',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Storage_Chest_2788': {
+        'hash': 2788,
+        'name': 'Storage_Chest',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'Chest': {
+            'hash': 3598052397,
+            'name': 'Chest'
+          }
+        }
+      },
+      'Top_Dock_1_2766': {
+        'hash': 2766,
+        'name': 'Top_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_2_2764': {
+        'hash': 2764,
+        'name': 'Top_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_3_2762': {
+        'hash': 2762,
+        'name': 'Top_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_4_2756': {
+        'hash': 2756,
+        'name': 'Top_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_5_2758': {
+        'hash': 2758,
+        'name': 'Top_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_6_2760': {
+        'hash': 2760,
+        'name': 'Top_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'Storage_Crate_Parts': {
+    'hash': 16574,
+    'name': 'Storage_Crate_Parts',
+    'embedded': {
+      'Storage_Crate_Parts_23406': {
+        'hash': 23406,
+        'name': 'Storage_Crate_Parts',
+        'savables': {}
+      }
+    }
+  },
+  'Storage_Crate_Redwood_Closed': {
+    'hash': 59594,
+    'name': 'Storage_Crate_Redwood_Closed',
+    'embedded': {
+      'Spawn_Content_29300': {
+        'hash': 29300,
+        'name': 'Spawn_Content',
+        'savables': {}
+      },
+      'Storage_Crate_Redwood_Closed_64282': {
+        'hash': 64282,
+        'name': 'Storage_Crate_Redwood_Closed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Storage_Crate_Redwood_Open': {
+    'hash': 32788,
+    'name': 'Storage_Crate_Redwood_Open',
+    'embedded': {
+      'Random_Spawn_Rectangle_22462': {
+        'hash': 22462,
+        'name': 'Random_Spawn_Rectangle',
+        'savables': {
+          'RandomSpawnRectangle': {
+            'hash': 3101665521,
+            'name': 'RandomSpawnRectangle'
+          }
+        }
+      },
+      'Spawn_Content_3812': {
+        'hash': 3812,
+        'name': 'Spawn_Content',
+        'savables': {}
+      },
+      'Storage_Crate_Redwood_Open_50750': {
+        'hash': 50750,
+        'name': 'Storage_Crate_Redwood_Open',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Street_Post': {
+    'hash': 57248,
+    'name': 'Street_Post',
+    'embedded': {
+      'Sign_Body_17004': {
+        'hash': 17004,
+        'name': 'Sign_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Street_Post_54666': {
+        'hash': 54666,
+        'name': 'Street_Post',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      },
+      'Visual_1_28010': {
+        'hash': 28010,
+        'name': 'Visual_1',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Visual_2_57532': {
+        'hash': 57532,
+        'name': 'Visual_2',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Visual_3_15494': {
+        'hash': 15494,
+        'name': 'Visual_3',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Visual_4_9368': {
+        'hash': 9368,
+        'name': 'Visual_4',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      }
+    }
+  },
+  'Structure_Chest': {
+    'hash': 35280,
+    'name': 'Structure_Chest',
+    'embedded': {
+      'Bottom_Dock_1_2780': {
+        'hash': 2780,
+        'name': 'Bottom_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_2_2778': {
+        'hash': 2778,
+        'name': 'Bottom_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_3_2776': {
+        'hash': 2776,
+        'name': 'Bottom_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_4_2770': {
+        'hash': 2770,
+        'name': 'Bottom_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_5_2772': {
+        'hash': 2772,
+        'name': 'Bottom_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Bottom_Dock_6_2774': {
+        'hash': 2774,
+        'name': 'Bottom_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Handle_Left_23970': {
+        'hash': 23970,
+        'name': 'Handle_Left',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_Right_23964': {
+        'hash': 23964,
+        'name': 'Handle_Right',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Lid_2768': {
+        'hash': 2768,
+        'name': 'Lid',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Storage_Chest_(1)_2788': {
+        'hash': 2788,
+        'name': 'Storage_Chest_(1)',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'Chest': {
+            'hash': 3598052397,
+            'name': 'Chest'
+          }
+        }
+      },
+      'Structure_Chest_21454': {
+        'hash': 21454,
+        'name': 'Structure_Chest',
+        'savables': {
+          'GeneratedLoot': {
+            'hash': 3642863935,
+            'name': 'GeneratedLoot'
+          }
+        }
+      },
+      'Top_Dock_1_2766': {
+        'hash': 2766,
+        'name': 'Top_Dock_1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_2_2764': {
+        'hash': 2764,
+        'name': 'Top_Dock_2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_3_2762': {
+        'hash': 2762,
+        'name': 'Top_Dock_3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_4_2756': {
+        'hash': 2756,
+        'name': 'Top_Dock_4',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_5_2758': {
+        'hash': 2758,
+        'name': 'Top_Dock_5',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Top_Dock_6_2760': {
+        'hash': 2760,
+        'name': 'Top_Dock_6',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      }
+    }
+  },
+  'TEMP_Hebios_Camp_Spawner_Barren': {
+    'hash': 33858,
+    'name': 'TEMP_Hebios_Camp_Spawner_Barren',
+    'embedded': {}
+  },
+  'TEMP_Hebios_Camp_Spawner_Valley': {
+    'hash': 33880,
+    'name': 'TEMP_Hebios_Camp_Spawner_Valley',
+    'embedded': {}
+  },
+  'TEMP_Watch_Tower_Spawner': {
+    'hash': 44032,
+    'name': 'TEMP_Watch_Tower_Spawner',
+    'embedded': {}
+  },
+  'Tab_Lever': {
+    'hash': 3354,
+    'name': 'Tab_Lever',
+    'embedded': {}
+  },
+  'Table_Placer': {
+    'hash': 25418,
+    'name': 'Table_Placer',
+    'embedded': {
+      'Table_Placer_29584': {
+        'hash': 29584,
+        'name': 'Table_Placer',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Tall_Support': {
+    'hash': 46506,
+    'name': 'Tall_Support',
+    'embedded': {
+      'Tall_Support_5348': {
+        'hash': 5348,
+        'name': 'Tall_Support',
+        'savables': {}
+      }
+    }
+  },
+  'Tall_Support_Beams': {
+    'hash': 5682,
+    'name': 'Tall_Support_Beams',
+    'embedded': {
+      'Tall_Support_Beams_5680': {
+        'hash': 5680,
+        'name': 'Tall_Support_Beams',
+        'savables': {}
+      }
+    }
+  },
+  'Targeted_Geyser': {
+    'hash': 60812,
+    'name': 'Targeted_Geyser',
+    'embedded': {
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Geyser_AI_29794': {
+        'hash': 29794,
+        'name': 'Geyser_AI',
+        'savables': {}
+      },
+      'Targeted_Geyser_37626': {
+        'hash': 37626,
+        'name': 'Targeted_Geyser',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'TeleportOnTrueLogic': {
+    'hash': 18260,
+    'name': 'TeleportOnTrueLogic',
+    'embedded': {
+      'TeleportOnTrueLogic_11330': {
+        'hash': 11330,
+        'name': 'TeleportOnTrueLogic',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'TeleportationPoint': {
+            'hash': 3146178080,
+            'name': 'TeleportationPoint'
+          }
+        }
+      }
+    }
+  },
+  'Teleport_Point': {
+    'hash': 33542,
+    'name': 'Teleport_Point',
+    'embedded': {}
+  },
+  'Teleporter_Puzzle': {
+    'hash': 19164,
+    'name': 'Teleporter_Puzzle',
+    'embedded': {
+      'Customization_Teleporter_2940': {
+        'hash': 2940,
+        'name': 'Customization_Teleporter',
+        'savables': {}
+      },
+      'Teleporter_Puzzle_7710': {
+        'hash': 7710,
+        'name': 'Teleporter_Puzzle',
+        'savables': {
+          'LogicVector3Receiver': {
+            'hash': 1228539097,
+            'name': 'LogicVector3Receiver'
+          },
+          'LogicVector3Sender': {
+            'hash': 2026743731,
+            'name': 'LogicVector3Sender'
+          },
+          'PositionProvider': {
+            'hash': 3538443740,
+            'name': 'PositionProvider'
+          },
+          'TeleportationPoint': {
+            'hash': 3146178080,
+            'name': 'TeleportationPoint'
+          }
+        }
+      }
+    }
+  },
+  'Teleporter_To_Customization': {
+    'hash': 60372,
+    'name': 'Teleporter_To_Customization',
+    'embedded': {
+      'Customization_Teleporter_27658': {
+        'hash': 27658,
+        'name': 'Customization_Teleporter',
+        'savables': {}
+      },
+      'Teleporter_To_Customization_60294': {
+        'hash': 60294,
+        'name': 'Teleporter_To_Customization',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Temp_Dynamic_Wall': {
+    'hash': 31628,
+    'name': 'Temp_Dynamic_Wall',
+    'embedded': {
+      'Temp_Dynamic_Wall_8038': {
+        'hash': 8038,
+        'name': 'Temp_Dynamic_Wall',
+        'savables': {}
+      }
+    }
+  },
+  'Test_Fire': {
+    'hash': 31268,
+    'name': 'Test_Fire',
+    'embedded': {
+      'Fire_30100': {
+        'hash': 30100,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          }
+        }
+      },
+      'Forge_Area_19102': {
+        'hash': 19102,
+        'name': 'Forge_Area',
+        'savables': {}
+      },
+      'Test_Fire_61848': {
+        'hash': 61848,
+        'name': 'Test_Fire',
+        'savables': {}
+      }
+    }
+  },
+  'Test_Serializable_Large': {
+    'hash': 57330,
+    'name': 'Test_Serializable_Large',
+    'embedded': {}
+  },
+  'Test_Serializable_Small': {
+    'hash': 51498,
+    'name': 'Test_Serializable_Small',
+    'embedded': {}
+  },
+  'Thick_Great_Sword_Blade': {
+    'hash': 25802,
+    'name': 'Thick_Great_Sword_Blade',
+    'embedded': {
+      'Heat_Point_Collection_64052': {
+        'hash': 64052,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_Large_SwordType_7796': {
+        'hash': 7796,
+        'name': 'Insert_Large_SwordType',
+        'savables': {}
+      },
+      'Thick_Great_Sword_Blade_84': {
+        'hash': 84,
+        'name': 'Thick_Great_Sword_Blade',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'metal_thickGreatsword_blade_full_geo_LOD0_2564': {
+        'hash': 2564,
+        'name': 'metal_thickGreatsword_blade_full_geo_LOD0',
+        'savables': {}
+      }
+    }
+  },
+  'Thin_Cloth_Medium_Square': {
+    'hash': 34570,
+    'name': 'Thin_Cloth_Medium_Square',
+    'embedded': {
+      'Thin_Cloth_Medium_Square_14710': {
+        'hash': 14710,
+        'name': 'Thin_Cloth_Medium_Square',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Timber_Bag': {
+    'hash': 25122,
+    'name': 'Timber_Bag',
+    'embedded': {
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Dock_TL_42990': {
+        'hash': 42990,
+        'name': 'Dock_TL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Interaction_Point_59032': {
+        'hash': 59032,
+        'name': 'Interaction_Point',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_30776': {
+        'hash': 30776,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Slot_Bag_Attach_55164': {
+        'hash': 55164,
+        'name': 'Slot_Bag_Attach',
+        'savables': {}
+      },
+      'Timber_Bag_43012': {
+        'hash': 43012,
+        'name': 'Timber_Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'basket_bag_handle_wraps_56574': {
+        'hash': 56574,
+        'name': 'basket_bag_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'basket_handle_56602': {
+        'hash': 56602,
+        'name': 'basket_handle',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_leather_pad_14826': {
+        'hash': 14826,
+        'name': 'timber_bag_leather_pad',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_plank_01_14822': {
+        'hash': 14822,
+        'name': 'timber_bag_plank_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_plank_02_14818': {
+        'hash': 14818,
+        'name': 'timber_bag_plank_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_plank_03_14814': {
+        'hash': 14814,
+        'name': 'timber_bag_plank_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_01_14810': {
+        'hash': 14810,
+        'name': 'timber_bag_ropeKnot_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_02_14806': {
+        'hash': 14806,
+        'name': 'timber_bag_ropeKnot_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_03_14802': {
+        'hash': 14802,
+        'name': 'timber_bag_ropeKnot_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_04_14798': {
+        'hash': 14798,
+        'name': 'timber_bag_ropeKnot_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_05_14794': {
+        'hash': 14794,
+        'name': 'timber_bag_ropeKnot_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_07_14890': {
+        'hash': 14890,
+        'name': 'timber_bag_ropeKnot_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeKnot_08_14886': {
+        'hash': 14886,
+        'name': 'timber_bag_ropeKnot_08',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_01_14882': {
+        'hash': 14882,
+        'name': 'timber_bag_ropeNotch_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_02_14878': {
+        'hash': 14878,
+        'name': 'timber_bag_ropeNotch_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_03_14874': {
+        'hash': 14874,
+        'name': 'timber_bag_ropeNotch_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_04_14870': {
+        'hash': 14870,
+        'name': 'timber_bag_ropeNotch_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_05_14866': {
+        'hash': 14866,
+        'name': 'timber_bag_ropeNotch_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_06_14862': {
+        'hash': 14862,
+        'name': 'timber_bag_ropeNotch_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_07_14858': {
+        'hash': 14858,
+        'name': 'timber_bag_ropeNotch_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_ropeNotch_08_14854': {
+        'hash': 14854,
+        'name': 'timber_bag_ropeNotch_08',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_010_14846': {
+        'hash': 14846,
+        'name': 'timber_bag_stick_010',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_011_14842': {
+        'hash': 14842,
+        'name': 'timber_bag_stick_011',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_01_14850': {
+        'hash': 14850,
+        'name': 'timber_bag_stick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_02_14838': {
+        'hash': 14838,
+        'name': 'timber_bag_stick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_03_14834': {
+        'hash': 14834,
+        'name': 'timber_bag_stick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_04_14830': {
+        'hash': 14830,
+        'name': 'timber_bag_stick_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_05_14790': {
+        'hash': 14790,
+        'name': 'timber_bag_stick_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_06_14786': {
+        'hash': 14786,
+        'name': 'timber_bag_stick_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_07_14782': {
+        'hash': 14782,
+        'name': 'timber_bag_stick_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_08_14778': {
+        'hash': 14778,
+        'name': 'timber_bag_stick_08',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_stick_09_14774': {
+        'hash': 14774,
+        'name': 'timber_bag_stick_09',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Timber_Side_Pouch_Attachment': {
+    'hash': 7102,
+    'name': 'Timber_Side_Pouch_Attachment',
+    'embedded': {
+      'Dock_45700': {
+        'hash': 45700,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62078': {
+        'hash': 62078,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Insert_Bag_Attach_7796': {
+        'hash': 7796,
+        'name': 'Insert_Bag_Attach',
+        'savables': {}
+      },
+      'Storage_52232': {
+        'hash': 52232,
+        'name': 'Storage',
+        'savables': {}
+      },
+      'Timber_Side_Pouch_Attachment_7868': {
+        'hash': 7868,
+        'name': 'Timber_Side_Pouch_Attachment',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'timber_bag_attachment_plank_01_358': {
+        'hash': 358,
+        'name': 'timber_bag_attachment_plank_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_ropeKnot_01_406': {
+        'hash': 406,
+        'name': 'timber_bag_attachment_ropeKnot_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_ropeKnot_02_402': {
+        'hash': 402,
+        'name': 'timber_bag_attachment_ropeKnot_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_ropeNotch_01_390': {
+        'hash': 390,
+        'name': 'timber_bag_attachment_ropeNotch_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_stick_01_386': {
+        'hash': 386,
+        'name': 'timber_bag_attachment_stick_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_stick_02_382': {
+        'hash': 382,
+        'name': 'timber_bag_attachment_stick_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_stick_03_378': {
+        'hash': 378,
+        'name': 'timber_bag_attachment_stick_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_stick_04_374': {
+        'hash': 374,
+        'name': 'timber_bag_attachment_stick_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_stick_05_370': {
+        'hash': 370,
+        'name': 'timber_bag_attachment_stick_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'timber_bag_attachment_stick_06_366': {
+        'hash': 366,
+        'name': 'timber_bag_attachment_stick_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Timed_Respawner': {
+    'hash': 32620,
+    'name': 'Timed_Respawner',
+    'embedded': {
+      'Timed_Respawner_32662': {
+        'hash': 32662,
+        'name': 'Timed_Respawner',
+        'savables': {
+          'RespawnOnDestroy': {
+            'hash': 830106687,
+            'name': 'RespawnOnDestroy'
+          }
+        }
+      }
+    }
+  },
+  'TimerLogic': {
+    'hash': 18490,
+    'name': 'TimerLogic',
+    'embedded': {
+      'TimerLogic_63978': {
+        'hash': 63978,
+        'name': 'TimerLogic',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'TimerLogic': {
+            'hash': 3109677933,
+            'name': 'TimerLogic'
+          }
+        }
+      }
+    }
+  },
+  'Tinder': {
+    'hash': 34122,
+    'name': 'Tinder',
+    'embedded': {
+      'Fire_8488': {
+        'hash': 8488,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Spawner_49628': {
+        'hash': 49628,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'Tinder_24372': {
+        'hash': 24372,
+        'name': 'Tinder',
+        'savables': {
+          'BasicDecay': {
+            'hash': 3801256786,
+            'name': 'BasicDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Flower_Bloom': {
+    'hash': 13022,
+    'name': 'Tomato_Flower_Bloom',
+    'embedded': {
+      'Tomato_Flower_Bloom_49826': {
+        'hash': 49826,
+        'name': 'Tomato_Flower_Bloom',
+        'savables': {}
+      }
+    }
+  },
+  'Tomato_Flower_Bud': {
+    'hash': 13024,
+    'name': 'Tomato_Flower_Bud',
+    'embedded': {
+      'Tomato_Flower_Bud_49898': {
+        'hash': 49898,
+        'name': 'Tomato_Flower_Bud',
+        'savables': {}
+      }
+    }
+  },
+  'Tomato_Full_Burnt': {
+    'hash': 38742,
+    'name': 'Tomato_Full_Burnt',
+    'embedded': {
+      'Cooking_57238': {
+        'hash': 57238,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Full_Burnt_38212': {
+        'hash': 38212,
+        'name': 'Tomato_Full_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Full_Cooked': {
+    'hash': 38098,
+    'name': 'Tomato_Full_Cooked',
+    'embedded': {
+      'Cooking_56718': {
+        'hash': 56718,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Full_Cooked_37568': {
+        'hash': 37568,
+        'name': 'Tomato_Full_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Full_Ripe': {
+    'hash': 37454,
+    'name': 'Tomato_Full_Ripe',
+    'embedded': {
+      'Cooking_56198': {
+        'hash': 56198,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Full_Ripe_36924': {
+        'hash': 36924,
+        'name': 'Tomato_Full_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Full_Unripe': {
+    'hash': 36810,
+    'name': 'Tomato_Full_Unripe',
+    'embedded': {
+      'Cooking_55678': {
+        'hash': 55678,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Full_Unripe_36280': {
+        'hash': 36280,
+        'name': 'Tomato_Full_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Growth': {
+    'hash': 19280,
+    'name': 'Tomato_Growth',
+    'embedded': {
+      'Tomato_Growth_33458': {
+        'hash': 33458,
+        'name': 'Tomato_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Half_Burnt': {
+    'hash': 57698,
+    'name': 'Tomato_Half_Burnt',
+    'embedded': {
+      'Cooking_30630': {
+        'hash': 30630,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Half_Burnt_57360': {
+        'hash': 57360,
+        'name': 'Tomato_Half_Burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Half_Cooked': {
+    'hash': 57294,
+    'name': 'Tomato_Half_Cooked',
+    'embedded': {
+      'Cooking_30288': {
+        'hash': 30288,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Half_Cooked_56956': {
+        'hash': 56956,
+        'name': 'Tomato_Half_Cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Half_Ripe': {
+    'hash': 56890,
+    'name': 'Tomato_Half_Ripe',
+    'embedded': {
+      'Cooking_29946': {
+        'hash': 29946,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Half_Ripe_56552': {
+        'hash': 56552,
+        'name': 'Tomato_Half_Ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Half_Unripe': {
+    'hash': 56486,
+    'name': 'Tomato_Half_Unripe',
+    'embedded': {
+      'Cooking_29604': {
+        'hash': 29604,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Tomato_Half_Unripe_56148': {
+        'hash': 56148,
+        'name': 'Tomato_Half_Unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Tree': {
+    'hash': 56492,
+    'name': 'Tomato_Tree',
+    'embedded': {
+      'Tomato_Tree_54408': {
+        'hash': 54408,
+        'name': 'Tomato_Tree',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Tree_Growth': {
+    'hash': 16358,
+    'name': 'Tomato_Tree_Growth',
+    'embedded': {
+      'Tomato_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Tomato_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Tree_Separated': {
+    'hash': 21548,
+    'name': 'Tomato_Tree_Separated',
+    'embedded': {}
+  },
+  'Tomato_Tree_Stage_1': {
+    'hash': 2384,
+    'name': 'Tomato_Tree_Stage_1',
+    'embedded': {
+      'Tomato_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Tomato_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'Tomato_Tree_Stage_2': {
+    'hash': 2542,
+    'name': 'Tomato_Tree_Stage_2',
+    'embedded': {
+      'Tomato_Tree_Stage_2_52164': {
+        'hash': 52164,
+        'name': 'Tomato_Tree_Stage_2',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Tomato_Tree_Stage_3': {
+    'hash': 2892,
+    'name': 'Tomato_Tree_Stage_3',
+    'embedded': {
+      'Tomato_Tree_Stage_3_23378': {
+        'hash': 23378,
+        'name': 'Tomato_Tree_Stage_3',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Torch': {
+    'hash': 56698,
+    'name': 'Torch',
+    'embedded': {
+      'Fire_30100': {
+        'hash': 30100,
+        'name': 'Fire',
+        'savables': {
+          'Fire': {
+            'hash': 3457519710,
+            'name': 'Fire'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Torch_30110': {
+        'hash': 30110,
+        'name': 'Torch',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Township_Bridge_Broken': {
+    'hash': 8620,
+    'name': 'Township_Bridge_Broken',
+    'embedded': {
+      'Township_Bridge_Broken_13660': {
+        'hash': 13660,
+        'name': 'Township_Bridge_Broken',
+        'savables': {}
+      }
+    }
+  },
+  'Township_Bridge_Fixed': {
+    'hash': 33334,
+    'name': 'Township_Bridge_Fixed',
+    'embedded': {
+      'Township_Bridge_Fixed_13518': {
+        'hash': 13518,
+        'name': 'Township_Bridge_Fixed',
+        'savables': {}
+      }
+    }
+  },
+  'Township_Bridge_Repair_Box': {
+    'hash': 60674,
+    'name': 'Township_Bridge_Repair_Box',
+    'embedded': {
+      'Cost_1_22852': {
+        'hash': 22852,
+        'name': 'Cost 1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_2_22786': {
+        'hash': 22786,
+        'name': 'Cost 2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Cost_3_22772': {
+        'hash': 22772,
+        'name': 'Cost 3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_1_22642': {
+        'hash': 22642,
+        'name': 'Dock 1',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_2_22692': {
+        'hash': 22692,
+        'name': 'Dock 2',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_3_22698': {
+        'hash': 22698,
+        'name': 'Dock 3',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Township_Bridge_Broken_60312': {
+        'hash': 60312,
+        'name': 'Township Bridge Broken',
+        'savables': {}
+      },
+      'Township_Bridge_Repair_Box_60672': {
+        'hash': 60672,
+        'name': 'Township Bridge Repair Box',
+        'savables': {
+          'RepairBox': {
+            'hash': 3820454400,
+            'name': 'RepairBox'
+          }
+        }
+      }
+    }
+  },
+  'Trade_Deck': {
+    'hash': 30016,
+    'name': 'Trade_Deck',
+    'embedded': {
+      'BuyCoinDisplay_3686': {
+        'hash': 3686,
+        'name': 'BuyCoinDisplay',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'BuyItemDisplay_3684': {
+        'hash': 3684,
+        'name': 'BuyItemDisplay',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'CoinTradeCounter_63408': {
+        'hash': 63408,
+        'name': 'CoinTradeCounter',
+        'savables': {
+          'ButtonCounter': {
+            'hash': 3901697682,
+            'name': 'ButtonCounter'
+          }
+        }
+      },
+      'Grab_14560': {
+        'hash': 14560,
+        'name': 'Grab',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grab_22452': {
+        'hash': 22452,
+        'name': 'Grab',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle_65280': {
+        'hash': 65280,
+        'name': 'Handle',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'ItemTradeCounters_404': {
+        'hash': 404,
+        'name': 'ItemTradeCounters',
+        'savables': {
+          'ButtonCounter': {
+            'hash': 3901697682,
+            'name': 'ButtonCounter'
+          }
+        }
+      },
+      'ProfitDock_52720': {
+        'hash': 52720,
+        'name': 'ProfitDock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'SellCoinDisplay_3680': {
+        'hash': 3680,
+        'name': 'SellCoinDisplay',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'SellItemDisplay_34750': {
+        'hash': 34750,
+        'name': 'SellItemDisplay',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'StockDock_50586': {
+        'hash': 50586,
+        'name': 'StockDock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'TaxDock_54312': {
+        'hash': 54312,
+        'name': 'TaxDock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'TaxLever_48782': {
+        'hash': 48782,
+        'name': 'TaxLever',
+        'savables': {
+          'Lever': {
+            'hash': 1594932294,
+            'name': 'Lever'
+          }
+        }
+      },
+      'TemporaryCoinDock_28320': {
+        'hash': 28320,
+        'name': 'TemporaryCoinDock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Trade_Deck_31038': {
+        'hash': 31038,
+        'name': 'Trade_Deck',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'TaxManager': {
+            'hash': 43510150,
+            'name': 'TaxManager'
+          },
+          'TradeVendor': {
+            'hash': 1645673210,
+            'name': 'TradeVendor'
+          }
+        }
+      }
+    }
+  },
+  'TraderPrototype': {
+    'hash': 28820,
+    'name': 'TraderPrototype',
+    'embedded': {}
+  },
+  'Training_Short_Sword_Blade_COLD': {
+    'hash': 1850,
+    'name': 'Training_Short_Sword_Blade_COLD',
+    'embedded': {
+      'Forged_Model_4044': {
+        'hash': 4044,
+        'name': 'Forged_Model',
+        'savables': {}
+      },
+      'Heat_Point_Collection_11428': {
+        'hash': 11428,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Training_Short_Sword_Blade_COLD_36330': {
+        'hash': 36330,
+        'name': 'Training_Short_Sword_Blade_COLD',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Training_Short_Sword_Blade_HOT': {
+    'hash': 13220,
+    'name': 'Training_Short_Sword_Blade_HOT',
+    'embedded': {
+      'Forged_Model_4044': {
+        'hash': 4044,
+        'name': 'Forged_Model',
+        'savables': {}
+      },
+      'Heat_Point_Collection_11814': {
+        'hash': 11814,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Training_Short_Sword_Blade_HOT_36330': {
+        'hash': 36330,
+        'name': 'Training_Short_Sword_Blade_HOT',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'ForgedPointCollection': {
+            'hash': 2272630171,
+            'name': 'ForgedPointCollection'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Tree': {
+    'hash': 8860,
+    'name': 'Tree',
+    'embedded': {
+      'Tree_54994': {
+        'hash': 54994,
+        'name': 'Tree',
+        'savables': {
+          'GrowthStageComponent': {
+            'hash': 751359624,
+            'name': 'GrowthStageComponent'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          },
+          'TreeDecay': {
+            'hash': 2042199192,
+            'name': 'TreeDecay'
+          },
+          'WoodcutTree': {
+            'hash': 1098050191,
+            'name': 'WoodcutTree'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Button_Spawner': {
+    'hash': 3934,
+    'name': 'Tree_Button_Spawner',
+    'embedded': {}
+  },
+  'Tree_Grower': {
+    'hash': 25934,
+    'name': 'Tree_Grower',
+    'embedded': {
+      'Tree_Grower_33458': {
+        'hash': 33458,
+        'name': 'Tree_Grower',
+        'savables': {
+          'TimeBasedStagedPrefab': {
+            'hash': 1085701614,
+            'name': 'TimeBasedStagedPrefab'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Grown': {
+    'hash': 30572,
+    'name': 'Tree_Grown',
+    'embedded': {
+      'Tree_Grown_53296': {
+        'hash': 53296,
+        'name': 'Tree_Grown',
+        'savables': {}
+      }
+    }
+  },
+  'Tree_Spawner_-_Any_Ash': {
+    'hash': 50794,
+    'name': 'Tree_Spawner_-_Any_Ash',
+    'embedded': {
+      'Tree_Spawner_-_Any_Ash_50788': {
+        'hash': 50788,
+        'name': 'Tree_Spawner_-_Any_Ash',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Spawner_-_Any_Birch': {
+    'hash': 570,
+    'name': 'Tree_Spawner_-_Any_Birch',
+    'embedded': {
+      'Tree_Spawner_-_Any_Birch_21194': {
+        'hash': 21194,
+        'name': 'Tree_Spawner_-_Any_Birch',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Spawner_-_Any_Oak': {
+    'hash': 48358,
+    'name': 'Tree_Spawner_-_Any_Oak',
+    'embedded': {
+      'Tree_Spawner_-_Any_Oak_21194': {
+        'hash': 21194,
+        'name': 'Tree_Spawner_-_Any_Oak',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Spawner_-_Any_Redwood': {
+    'hash': 546,
+    'name': 'Tree_Spawner_-_Any_Redwood',
+    'embedded': {
+      'Tree_Spawner_-_Any_Redwood_21194': {
+        'hash': 21194,
+        'name': 'Tree_Spawner_-_Any_Redwood',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Spawner_-_Any_Standard': {
+    'hash': 15738,
+    'name': 'Tree_Spawner_-_Any_Standard',
+    'embedded': {
+      'Tree_Spawner_-_Any_Standard_21194': {
+        'hash': 21194,
+        'name': 'Tree_Spawner_-_Any_Standard',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Spawner_-_Any_TEMP_TEST': {
+    'hash': 58970,
+    'name': 'Tree_Spawner_-_Any_TEMP_TEST',
+    'embedded': {}
+  },
+  'Tree_Spawner_-_Any_Walnut': {
+    'hash': 34710,
+    'name': 'Tree_Spawner_-_Any_Walnut',
+    'embedded': {
+      'Tree_Spawner_-_Any_Walnut_21194': {
+        'hash': 21194,
+        'name': 'Tree_Spawner_-_Any_Walnut',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Spawner_-_Small_Standard': {
+    'hash': 57286,
+    'name': 'Tree_Spawner_-_Small_Standard',
+    'embedded': {
+      'Tree_Spawner_-_Small_Standard_21194': {
+        'hash': 21194,
+        'name': 'Tree_Spawner_-_Small_Standard',
+        'savables': {
+          'TreeSpawner': {
+            'hash': 3638500874,
+            'name': 'TreeSpawner'
+          }
+        }
+      }
+    }
+  },
+  'Tree_Young': {
+    'hash': 30570,
+    'name': 'Tree_Young',
+    'embedded': {
+      'Tree_Young_53362': {
+        'hash': 53362,
+        'name': 'Tree_Young',
+        'savables': {}
+      }
+    }
+  },
+  'Trial_Spawner_MD-T1': {
+    'hash': 62144,
+    'name': 'Trial_Spawner_MD-T1',
+    'embedded': {
+      'Trial_Spawner_MD-T1_37438': {
+        'hash': 37438,
+        'name': 'Trial_Spawner_MD-T1',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_MD-T2': {
+    'hash': 60910,
+    'name': 'Trial_Spawner_MD-T2',
+    'embedded': {
+      'Trial_Spawner_MD-T2_37438': {
+        'hash': 37438,
+        'name': 'Trial_Spawner_MD-T2',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_MD-T3': {
+    'hash': 52988,
+    'name': 'Trial_Spawner_MD-T3',
+    'embedded': {
+      'Trial_Spawner_MD-T3_37438': {
+        'hash': 37438,
+        'name': 'Trial_Spawner_MD-T3',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_MD-W1': {
+    'hash': 32210,
+    'name': 'Trial_Spawner_MD-W1',
+    'embedded': {
+      'Trial_Spawner_MD-W1_52626': {
+        'hash': 52626,
+        'name': 'Trial_Spawner_MD-W1',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_MD-W2': {
+    'hash': 50818,
+    'name': 'Trial_Spawner_MD-W2',
+    'embedded': {
+      'Trial_Spawner_MD-W2_52626': {
+        'hash': 52626,
+        'name': 'Trial_Spawner_MD-W2',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_T-1': {
+    'hash': 7744,
+    'name': 'Trial_Spawner_T-1',
+    'embedded': {
+      'Trial_Spawner_T-1_37438': {
+        'hash': 37438,
+        'name': 'Trial_Spawner_T-1',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_T-2': {
+    'hash': 40198,
+    'name': 'Trial_Spawner_T-2',
+    'embedded': {
+      'Trial_Spawner_T-2_9898': {
+        'hash': 9898,
+        'name': 'Trial_Spawner_T-2',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_T-3': {
+    'hash': 45096,
+    'name': 'Trial_Spawner_T-3',
+    'embedded': {
+      'Trial_Spawner_T-3_37438': {
+        'hash': 37438,
+        'name': 'Trial_Spawner_T-3',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_T-3-Myth': {
+    'hash': 49994,
+    'name': 'Trial_Spawner_T-3-Myth',
+    'embedded': {
+      'Trial_Spawner_T-3-Myth_37438': {
+        'hash': 37438,
+        'name': 'Trial_Spawner_T-3-Myth',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_W-1': {
+    'hash': 33084,
+    'name': 'Trial_Spawner_W-1',
+    'embedded': {
+      'Trial_Spawner_W-1_52626': {
+        'hash': 52626,
+        'name': 'Trial_Spawner_W-1',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_W-2': {
+    'hash': 18696,
+    'name': 'Trial_Spawner_W-2',
+    'embedded': {
+      'Trial_Spawner_W-2_52626': {
+        'hash': 52626,
+        'name': 'Trial_Spawner_W-2',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_W-2-Crys': {
+    'hash': 58286,
+    'name': 'Trial_Spawner_W-2-Crys',
+    'embedded': {
+      'Trial_Spawner_W-2-Crys_52626': {
+        'hash': 52626,
+        'name': 'Trial_Spawner_W-2-Crys',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Trial_Spawner_W-3': {
+    'hash': 42624,
+    'name': 'Trial_Spawner_W-3',
+    'embedded': {
+      'Trial_Spawner_W-3_52626': {
+        'hash': 52626,
+        'name': 'Trial_Spawner_W-3',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Turabada': {
+    'hash': 13804,
+    'name': 'Turabada',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_13756': {
+        'hash': 13756,
+        'name': 'Turabada',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Arm': {
+    'hash': 15584,
+    'name': 'Turabada_Arm',
+    'embedded': {
+      'Insert_HammerType_End_Cap_52192': {
+        'hash': 52192,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      },
+      'Turabada_Arm_15540': {
+        'hash': 15540,
+        'name': 'Turabada_Arm',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Copper_Destroy_Variant': {
+    'hash': 34850,
+    'name': 'Turabada_Copper_Destroy_Variant',
+    'embedded': {
+      'Turabada_Copper_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Copper_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Copper_Trial_Variant': {
+    'hash': 14248,
+    'name': 'Turabada_Copper_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Copper_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Copper_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Copper_Variant': {
+    'hash': 39056,
+    'name': 'Turabada_Copper_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Copper_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Copper_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Destroy': {
+    'hash': 37508,
+    'name': 'Turabada_Destroy',
+    'embedded': {
+      'Turabada_Destroy_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Destroy',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Gold_Destroy_Variant': {
+    'hash': 15310,
+    'name': 'Turabada_Gold_Destroy_Variant',
+    'embedded': {
+      'Turabada_Gold_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Gold_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Gold_Trial_Variant': {
+    'hash': 15506,
+    'name': 'Turabada_Gold_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Gold_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Gold_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Gold_Variant': {
+    'hash': 37176,
+    'name': 'Turabada_Gold_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Gold_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Gold_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Hub_Dynamic': {
+    'hash': 48478,
+    'name': 'Turabada_Hub_Dynamic',
+    'embedded': {
+      'Core_Spawn_16554': {
+        'hash': 16554,
+        'name': 'Core_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Door_Blockage_Spawn_47616': {
+        'hash': 47616,
+        'name': 'Door_Blockage_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Enemy_Spawn_30256': {
+        'hash': 30256,
+        'name': 'Enemy_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Turabada_Hub_Dynamic_53304': {
+        'hash': 53304,
+        'name': 'Turabada_Hub_Dynamic',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Iron_Destroy_Variant': {
+    'hash': 42690,
+    'name': 'Turabada_Iron_Destroy_Variant',
+    'embedded': {
+      'Turabada_Iron_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Iron_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Iron_Trial_Variant': {
+    'hash': 16684,
+    'name': 'Turabada_Iron_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Iron_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Iron_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Iron_Variant': {
+    'hash': 8298,
+    'name': 'Turabada_Iron_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Iron_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Iron_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Large_Destroy_Variant': {
+    'hash': 63178,
+    'name': 'Turabada_Large_Destroy_Variant',
+    'embedded': {
+      'Turabada_Large_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Large_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Large_Trial_Variant': {
+    'hash': 17814,
+    'name': 'Turabada_Large_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Large_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Large_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Large_Variant': {
+    'hash': 41172,
+    'name': 'Turabada_Large_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Large_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Large_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Mythril_Destroy_Variant': {
+    'hash': 45488,
+    'name': 'Turabada_Mythril_Destroy_Variant',
+    'embedded': {
+      'Turabada_Mythril_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Mythril_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Mythril_Trial_Variant': {
+    'hash': 18722,
+    'name': 'Turabada_Mythril_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Mythril_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Mythril_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Mythril_Variant': {
+    'hash': 62968,
+    'name': 'Turabada_Mythril_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Mythril_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Mythril_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Preview': {
+    'hash': 49464,
+    'name': 'Turabada_Preview',
+    'embedded': {}
+  },
+  'Turabada_Shard_Core': {
+    'hash': 7900,
+    'name': 'Turabada_Shard_Core',
+    'embedded': {
+      'Chisel_Piece_58818': {
+        'hash': 58818,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58820': {
+        'hash': 58820,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58822': {
+        'hash': 58822,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58824': {
+        'hash': 58824,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58826': {
+        'hash': 58826,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58828': {
+        'hash': 58828,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58830': {
+        'hash': 58830,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58832': {
+        'hash': 58832,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58834': {
+        'hash': 58834,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58836': {
+        'hash': 58836,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58838': {
+        'hash': 58838,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58840': {
+        'hash': 58840,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Chisel_Piece_58842': {
+        'hash': 58842,
+        'name': 'Chisel_Piece',
+        'savables': {}
+      },
+      'Explosion_44800': {
+        'hash': 44800,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Turabada_Shard_Core_7884': {
+        'hash': 7884,
+        'name': 'Turabada_Shard_Core',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Short_Destroy_Variant': {
+    'hash': 48002,
+    'name': 'Turabada_Short_Destroy_Variant',
+    'embedded': {
+      'Turabada_Short_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Short_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Short_Trial_Variant': {
+    'hash': 19936,
+    'name': 'Turabada_Short_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Short_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Short_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Short_Variant': {
+    'hash': 63878,
+    'name': 'Turabada_Short_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Short_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Short_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Silver_Destroy_Variant': {
+    'hash': 1960,
+    'name': 'Turabada_Silver_Destroy_Variant',
+    'embedded': {
+      'Turabada_Silver_Destroy_Variant_37492': {
+        'hash': 37492,
+        'name': 'Turabada_Silver_Destroy_Variant',
+        'savables': {}
+      }
+    }
+  },
+  'Turabada_Silver_Trial_Variant': {
+    'hash': 20844,
+    'name': 'Turabada_Silver_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Silver_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Silver_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Silver_Variant': {
+    'hash': 45716,
+    'name': 'Turabada_Silver_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Silver_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Silver_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Spawner_Automatic': {
+    'hash': 51652,
+    'name': 'Turabada_Spawner_Automatic',
+    'embedded': {
+      'Turabada_Spawner_Automatic_26726': {
+        'hash': 26726,
+        'name': 'Turabada_Spawner_Automatic',
+        'savables': {}
+      },
+      'caveRock_34072': {
+        'hash': 34072,
+        'name': 'caveRock',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Spawner_Reactive': {
+    'hash': 27188,
+    'name': 'Turabada_Spawner_Reactive',
+    'embedded': {
+      'Reactive_AI_17314': {
+        'hash': 17314,
+        'name': 'Reactive_AI',
+        'savables': {}
+      },
+      'Turabada_Spawner_Reactive_26726': {
+        'hash': 26726,
+        'name': 'Turabada_Spawner_Reactive',
+        'savables': {}
+      },
+      'caveRock_34072': {
+        'hash': 34072,
+        'name': 'caveRock',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Turabada_Trial_Variant': {
+    'hash': 21882,
+    'name': 'Turabada_Trial_Variant',
+    'embedded': {
+      'Arm_Collision_L_40528': {
+        'hash': 40528,
+        'name': 'Arm_Collision_L',
+        'savables': {}
+      },
+      'Arm_Collision_R_42784': {
+        'hash': 42784,
+        'name': 'Arm_Collision_R',
+        'savables': {}
+      },
+      'Explosion_58370': {
+        'hash': 58370,
+        'name': 'Explosion',
+        'savables': {}
+      },
+      'Killed_Drops_63174': {
+        'hash': 63174,
+        'name': 'Killed_Drops',
+        'savables': {}
+      },
+      'Target_Collector_10522': {
+        'hash': 10522,
+        'name': 'Target_Collector',
+        'savables': {}
+      },
+      'Turabada_01_2540': {
+        'hash': 2540,
+        'name': 'Turabada_01',
+        'savables': {}
+      },
+      'Turabada_AI_10656': {
+        'hash': 10656,
+        'name': 'Turabada_AI',
+        'savables': {
+          'LevelStatModifier': {
+            'hash': 788405183,
+            'name': 'LevelStatModifier'
+          }
+        }
+      },
+      'Turabada_Trial_Variant_13756': {
+        'hash': 13756,
+        'name': 'Turabada_Trial_Variant',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'UnplacedMetalWallHook': {
+    'hash': 18972,
+    'name': 'UnplacedMetalWallHook',
+    'embedded': {
+      'Heat_Point_Collection_11020': {
+        'hash': 11020,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'UnplacedMetalWallHook_26498': {
+        'hash': 26498,
+        'name': 'UnplacedMetalWallHook',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'VR_Player_Character_New': {
+    'hash': 49582,
+    'name': 'VR_Player_Character_New',
+    'embedded': {}
+  },
+  'Vacuum': {
+    'hash': 8586,
+    'name': 'Vacuum',
+    'embedded': {
+      'Dock_42390': {
+        'hash': 42390,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Vacuum_7480': {
+        'hash': 7480,
+        'name': 'Vacuum',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Vegetable_Ragu_Recipe_Burnt_Stew': {
+    'hash': 58092,
+    'name': 'Vegetable_Ragu_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Vegetable_Ragu_Recipe_Cooked_Stew': {
+    'hash': 58074,
+    'name': 'Vegetable_Ragu_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Vegetable_Ragu_Recipe_Raw_Stew': {
+    'hash': 58050,
+    'name': 'Vegetable_Ragu_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Vine_Attack_Fern': {
+    'hash': 24402,
+    'name': 'Vine_Attack_Fern',
+    'embedded': {
+      'Death_Fern_AI_29794': {
+        'hash': 29794,
+        'name': 'Death_Fern_AI',
+        'savables': {}
+      },
+      'Emit_Gas_Spawner_16984': {
+        'hash': 16984,
+        'name': 'Emit_Gas_Spawner',
+        'savables': {}
+      },
+      'Erupt_Area_19858': {
+        'hash': 19858,
+        'name': 'Erupt_Area',
+        'savables': {}
+      },
+      'Impactor_63610': {
+        'hash': 63610,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Impactor_65072': {
+        'hash': 65072,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Impactor_65078': {
+        'hash': 65078,
+        'name': 'Impactor',
+        'savables': {}
+      },
+      'Mesh_15308': {
+        'hash': 15308,
+        'name': 'Mesh',
+        'savables': {}
+      },
+      'Vine_Attack_Fern_37626': {
+        'hash': 37626,
+        'name': 'Vine_Attack_Fern',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Vine_Boulder_01': {
+    'hash': 31088,
+    'name': 'Vine_Boulder_01',
+    'embedded': {
+      'Directional_Encounter_63404': {
+        'hash': 63404,
+        'name': 'Directional_Encounter',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Vine_Boulder_01_62528': {
+        'hash': 62528,
+        'name': 'Vine_Boulder_01',
+        'savables': {}
+      }
+    }
+  },
+  'Vision_Recipe_Burnt_Stew': {
+    'hash': 58138,
+    'name': 'Vision_Recipe_Burnt_Stew',
+    'embedded': {}
+  },
+  'Vision_Recipe_Cooked_Stew': {
+    'hash': 58120,
+    'name': 'Vision_Recipe_Cooked_Stew',
+    'embedded': {}
+  },
+  'Vision_Recipe_Raw_Stew': {
+    'hash': 58162,
+    'name': 'Vision_Recipe_Raw_Stew',
+    'embedded': {}
+  },
+  'Wakizashi': {
+    'hash': 29856,
+    'name': 'Wakizashi',
+    'embedded': {
+      'Wakizashi_36330': {
+        'hash': 36330,
+        'name': 'Wakizashi',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'Enchantable': {
+            'hash': 4134534481,
+            'name': 'Enchantable'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Walk_Air': {
+    'hash': 50936,
+    'name': 'Walk_Air',
+    'embedded': {}
+  },
+  'Wall_Shelf': {
+    'hash': 15548,
+    'name': 'Wall_Shelf',
+    'embedded': {
+      'Dock_62060': {
+        'hash': 62060,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62062': {
+        'hash': 62062,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62064': {
+        'hash': 62064,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_62066': {
+        'hash': 62066,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Wall_Shelf_62464': {
+        'hash': 62464,
+        'name': 'Wall_Shelf',
+        'savables': {}
+      }
+    }
+  },
+  'Wall_Street_Post': {
+    'hash': 50078,
+    'name': 'Wall_Street_Post',
+    'embedded': {
+      'Sign_Body_13458': {
+        'hash': 13458,
+        'name': 'Sign_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Visual_1_44280': {
+        'hash': 44280,
+        'name': 'Visual_1',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Visual_2_38710': {
+        'hash': 38710,
+        'name': 'Visual_2',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Visual_3_23608': {
+        'hash': 23608,
+        'name': 'Visual_3',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Visual_4_16452': {
+        'hash': 16452,
+        'name': 'Visual_4',
+        'savables': {
+          'MeshPlacement': {
+            'hash': 2169673426,
+            'name': 'MeshPlacement'
+          }
+        }
+      },
+      'Wall_Street_Post_16266': {
+        'hash': 16266,
+        'name': 'Wall_Street_Post',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Wall_Torch_Holder': {
+    'hash': 3786,
+    'name': 'Wall_Torch_Holder',
+    'embedded': {
+      'Torch_Dock_5626': {
+        'hash': 5626,
+        'name': 'Torch_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Wall_Torch_Holder_54416': {
+        'hash': 54416,
+        'name': 'Wall_Torch_Holder',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Wall_Torch_Holder_Puzzle': {
+    'hash': 30196,
+    'name': 'Wall_Torch_Holder_Puzzle',
+    'embedded': {
+      'Extra_Logic_1_49636': {
+        'hash': 49636,
+        'name': 'Extra_Logic_1',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          }
+        }
+      },
+      'Torch_Dock_5626': {
+        'hash': 5626,
+        'name': 'Torch_Dock',
+        'savables': {
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          },
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          },
+          'PlaceItemPuzzleLogic': {
+            'hash': 1001395212,
+            'name': 'PlaceItemPuzzleLogic'
+          }
+        }
+      },
+      'Wall_Torch_Holder_Puzzle_30194': {
+        'hash': 30194,
+        'name': 'Wall_Torch_Holder_Puzzle',
+        'savables': {}
+      }
+    }
+  },
+  'Walnut_Gotera_Bomb_Dart': {
+    'hash': 39716,
+    'name': 'Walnut_Gotera_Bomb_Dart',
+    'embedded': {
+      'Dart_62940': {
+        'hash': 62940,
+        'name': 'Dart',
+        'savables': {}
+      },
+      'Walnut_Gotera_Bomb_Dart_3092': {
+        'hash': 3092,
+        'name': 'Walnut_Gotera_Bomb_Dart',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Walnut_Tree_Growth': {
+    'hash': 48268,
+    'name': 'Walnut_Tree_Growth',
+    'embedded': {
+      'Walnut_Tree_Growth_33458': {
+        'hash': 33458,
+        'name': 'Walnut_Tree_Growth',
+        'savables': {
+          'GrowerComponent': {
+            'hash': 3402094521,
+            'name': 'GrowerComponent'
+          }
+        }
+      }
+    }
+  },
+  'Walnut_Tree_Seed': {
+    'hash': 44172,
+    'name': 'Walnut_Tree_Seed',
+    'embedded': {
+      'Walnut_Tree_Seed_35258': {
+        'hash': 35258,
+        'name': 'Walnut_Tree_Seed',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Walnut_Tree_Stage_1': {
+    'hash': 26568,
+    'name': 'Walnut_Tree_Stage_1',
+    'embedded': {
+      'Walnut_Tree_Stage_1_63514': {
+        'hash': 63514,
+        'name': 'Walnut_Tree_Stage_1',
+        'savables': {}
+      }
+    }
+  },
+  'WarHammer': {
+    'hash': 9630,
+    'name': 'WarHammer',
+    'embedded': {
+      'Heat_Point_Collection_1720': {
+        'hash': 1720,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_52192': {
+        'hash': 52192,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      },
+      'WarHammer_42978': {
+        'hash': 42978,
+        'name': 'WarHammer',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Water_Well_Dynamic': {
+    'hash': 14364,
+    'name': 'Water_Well_Dynamic',
+    'embedded': {}
+  },
+  'Water_Well_Tunnel_Dynamic': {
+    'hash': 12356,
+    'name': 'Water_Well_Tunnel_Dynamic',
+    'embedded': {
+      'Dock_2780': {
+        'hash': 2780,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60224': {
+        'hash': 60224,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60226': {
+        'hash': 60226,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60228': {
+        'hash': 60228,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60234': {
+        'hash': 60234,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60236': {
+        'hash': 60236,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60238': {
+        'hash': 60238,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60244': {
+        'hash': 60244,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_60246': {
+        'hash': 60246,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Water_Well_Tunnel_Dynamic_14816': {
+        'hash': 14816,
+        'name': 'Water_Well_Tunnel_Dynamic',
+        'savables': {}
+      }
+    }
+  },
+  'Weapon_Rack_Wall': {
+    'hash': 13062,
+    'name': 'Weapon_Rack_Wall',
+    'embedded': {
+      'ToolDock_(1)_26316': {
+        'hash': 26316,
+        'name': 'ToolDock_(1)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'ToolDock_(2)_26308': {
+        'hash': 26308,
+        'name': 'ToolDock_(2)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'ToolDock_(3)_26304': {
+        'hash': 26304,
+        'name': 'ToolDock_(3)',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'ToolDock_5626': {
+        'hash': 5626,
+        'name': 'ToolDock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Weapon_Rack_Wall_9260': {
+        'hash': 9260,
+        'name': 'Weapon_Rack_Wall',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'Wedge_Training': {
+    'hash': 53570,
+    'name': 'Wedge_Training',
+    'embedded': {
+      'Wedge_Training_53566': {
+        'hash': 53566,
+        'name': 'Wedge_Training',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      }
+    }
+  },
+  'Weight_Gauge': {
+    'hash': 48306,
+    'name': 'Weight_Gauge',
+    'embedded': {
+      'Weight_Gauge_48288': {
+        'hash': 48288,
+        'name': 'Weight_Gauge',
+        'savables': {}
+      }
+    }
+  },
+  'WheelBridge': {
+    'hash': 7252,
+    'name': 'WheelBridge',
+    'embedded': {
+      'Grip_(1)_54050': {
+        'hash': 54050,
+        'name': 'Grip_(1)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(2)_54614': {
+        'hash': 54614,
+        'name': 'Grip_(2)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(3)_56370': {
+        'hash': 56370,
+        'name': 'Grip_(3)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(4)_53470': {
+        'hash': 53470,
+        'name': 'Grip_(4)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(5)_19654': {
+        'hash': 19654,
+        'name': 'Grip_(5)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_56728': {
+        'hash': 56728,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'WheelBridge_43884': {
+        'hash': 43884,
+        'name': 'WheelBridge',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          },
+          'RotatePickup': {
+            'hash': 2498617949,
+            'name': 'RotatePickup'
+          }
+        }
+      },
+      'wheel_origin_43868': {
+        'hash': 43868,
+        'name': 'wheel_origin',
+        'savables': {
+          'WheelGrab': {
+            'hash': 320224849,
+            'name': 'WheelGrab'
+          }
+        }
+      }
+    }
+  },
+  'WheelPuzzle': {
+    'hash': 52364,
+    'name': 'WheelPuzzle',
+    'embedded': {
+      'Grip_(1)_54050': {
+        'hash': 54050,
+        'name': 'Grip_(1)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(2)_54614': {
+        'hash': 54614,
+        'name': 'Grip_(2)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(3)_56370': {
+        'hash': 56370,
+        'name': 'Grip_(3)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(4)_53470': {
+        'hash': 53470,
+        'name': 'Grip_(4)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_(5)_19654': {
+        'hash': 19654,
+        'name': 'Grip_(5)',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Grip_56728': {
+        'hash': 56728,
+        'name': 'Grip',
+        'savables': {
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'WheelPuzzle_43884': {
+        'hash': 43884,
+        'name': 'WheelPuzzle',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'LogicFloatSender': {
+            'hash': 2120963769,
+            'name': 'LogicFloatSender'
+          },
+          'RotatePickup': {
+            'hash': 2498617949,
+            'name': 'RotatePickup'
+          }
+        }
+      },
+      'wheel_origin_43868': {
+        'hash': 43868,
+        'name': 'wheel_origin',
+        'savables': {
+          'WheelGrab': {
+            'hash': 320224849,
+            'name': 'WheelGrab'
+          }
+        }
+      }
+    }
+  },
+  'WheelPuzzleOLD': {
+    'hash': 61964,
+    'name': 'WheelPuzzleOLD',
+    'embedded': {}
+  },
+  'White_Gold_Ingot': {
+    'hash': 13158,
+    'name': 'White_Gold_Ingot',
+    'embedded': {
+      'Heat_Point_Collection_13798': {
+        'hash': 13798,
+        'name': 'Heat_Point_Collection',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'White_Gold_Ingot_32738': {
+        'hash': 32738,
+        'name': 'White_Gold_Ingot',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_Base': {
+    'hash': 28312,
+    'name': 'Woodcut_Ash_LeafClump_Base',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_Base_28328': {
+        'hash': 28328,
+        'name': 'Woodcut_Ash_LeafClump_Base',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C1C1': {
+    'hash': 44892,
+    'name': 'Woodcut_Ash_LeafClump_C1C1',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C1C1_44890': {
+        'hash': 44890,
+        'name': 'Woodcut_Ash_LeafClump_C1C1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C1C2': {
+    'hash': 34638,
+    'name': 'Woodcut_Ash_LeafClump_C1C2',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C1C2_34636': {
+        'hash': 34636,
+        'name': 'Woodcut_Ash_LeafClump_C1C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C1C2_E': {
+    'hash': 47502,
+    'name': 'Woodcut_Ash_LeafClump_C1C2_E',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C1C2_E_47500': {
+        'hash': 47500,
+        'name': 'Woodcut_Ash_LeafClump_C1C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C1_E': {
+    'hash': 47458,
+    'name': 'Woodcut_Ash_LeafClump_C1_E',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C1_E_47456': {
+        'hash': 47456,
+        'name': 'Woodcut_Ash_LeafClump_C1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C1_E_1': {
+    'hash': 14074,
+    'name': 'Woodcut_Ash_LeafClump_C1_E_1',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C1_E_1_14072': {
+        'hash': 14072,
+        'name': 'Woodcut_Ash_LeafClump_C1_E_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C1_E_2': {
+    'hash': 40722,
+    'name': 'Woodcut_Ash_LeafClump_C1_E_2',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C1_E_2_40720': {
+        'hash': 40720,
+        'name': 'Woodcut_Ash_LeafClump_C1_E_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C2C2': {
+    'hash': 44908,
+    'name': 'Woodcut_Ash_LeafClump_C2C2',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C2C2_44906': {
+        'hash': 44906,
+        'name': 'Woodcut_Ash_LeafClump_C2C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C2C3': {
+    'hash': 9426,
+    'name': 'Woodcut_Ash_LeafClump_C2C3',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C2C3_9424': {
+        'hash': 9424,
+        'name': 'Woodcut_Ash_LeafClump_C2C3',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C2C3_E': {
+    'hash': 57802,
+    'name': 'Woodcut_Ash_LeafClump_C2C3_E',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C2C3_E_57800': {
+        'hash': 57800,
+        'name': 'Woodcut_Ash_LeafClump_C2C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C2_E': {
+    'hash': 29976,
+    'name': 'Woodcut_Ash_LeafClump_C2_E',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C2_E_29974': {
+        'hash': 29974,
+        'name': 'Woodcut_Ash_LeafClump_C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C2_E_1': {
+    'hash': 24422,
+    'name': 'Woodcut_Ash_LeafClump_C2_E_1',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C2_E_1_24420': {
+        'hash': 24420,
+        'name': 'Woodcut_Ash_LeafClump_C2_E_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C3C3': {
+    'hash': 10682,
+    'name': 'Woodcut_Ash_LeafClump_C3C3',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C3C3_10680': {
+        'hash': 10680,
+        'name': 'Woodcut_Ash_LeafClump_C3C3',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_LeafClump_C3_E': {
+    'hash': 57250,
+    'name': 'Woodcut_Ash_LeafClump_C3_E',
+    'embedded': {
+      'Woodcut_Ash_LeafClump_C3_E_57248': {
+        'hash': 57248,
+        'name': 'Woodcut_Ash_LeafClump_C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Ash_Seed_Spawner_Attachment': {
+    'hash': 16054,
+    'name': 'Woodcut_Ash_Seed_Spawner_Attachment',
+    'embedded': {
+      'Woodcut_Ash_Seed_Spawner_Attachment_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Ash_Seed_Spawner_Attachment',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B0_B0': {
+    'hash': 11470,
+    'name': 'Woodcut_B0_B0',
+    'embedded': {
+      'Top_8056': {
+        'hash': 8056,
+        'name': 'Top_8056',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B0_B0_S-30': {
+    'hash': 19224,
+    'name': 'Woodcut_B0_B0_S-30',
+    'embedded': {
+      'Stick_53710': {
+        'hash': 53710,
+        'name': 'Stick',
+        'savables': {}
+      },
+      'Top_53706': {
+        'hash': 53706,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_B0_B0_S-30_35608': {
+        'hash': 35608,
+        'name': 'Woodcut_B0_B0_S-30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_B0_B0_S15': {
+    'hash': 35014,
+    'name': 'Woodcut_B0_B0_S15',
+    'embedded': {
+      'Top_53706': {
+        'hash': 53706,
+        'name': 'Top_53706',
+        'savables': {}
+      },
+      'Stick_53710': {
+        'hash': 53710,
+        'name': 'Stick_53710',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B0_B0_S30': {
+    'hash': 36844,
+    'name': 'Woodcut_B0_B0_S30',
+    'embedded': {
+      'Stick_53710': {
+        'hash': 53710,
+        'name': 'Stick',
+        'savables': {}
+      },
+      'Top_53706': {
+        'hash': 53706,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_B0_B0_S30_35608': {
+        'hash': 35608,
+        'name': 'Woodcut_B0_B0_S30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_B0_B0_S30_S30': {
+    'hash': 6224,
+    'name': 'Woodcut_B0_B0_S30_S30',
+    'embedded': {
+      'Branch_1_20342': {
+        'hash': 20342,
+        'name': 'Branch_1',
+        'savables': {}
+      },
+      'Stick_1_20338': {
+        'hash': 20338,
+        'name': 'Stick_1',
+        'savables': {}
+      },
+      'Stick_2_55820': {
+        'hash': 55820,
+        'name': 'Stick_2',
+        'savables': {}
+      },
+      'Woodcut_B0_B0_S30_S30_6218': {
+        'hash': 6218,
+        'name': 'Woodcut_B0_B0_S30_S30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_B0_B15_B30': {
+    'hash': 35020,
+    'name': 'Woodcut_B0_B15_B30',
+    'embedded': {
+      'Branch_1_20342': {
+        'hash': 20342,
+        'name': 'Branch_1_20342',
+        'savables': {}
+      },
+      'Branch_2_20338': {
+        'hash': 20338,
+        'name': 'Branch_2_20338',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B0_B30_S30': {
+    'hash': 51486,
+    'name': 'Woodcut_B0_B30_S30',
+    'embedded': {
+      'Stick_51478': {
+        'hash': 51478,
+        'name': 'Stick',
+        'savables': {}
+      },
+      'Top_51476': {
+        'hash': 51476,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_B0_B30_S30_51474': {
+        'hash': 51474,
+        'name': 'Woodcut_B0_B30_S30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_B0_E': {
+    'hash': 29444,
+    'name': 'Woodcut_B0_E',
+    'embedded': {}
+  },
+  'Woodcut_B0_S0_S30': {
+    'hash': 35028,
+    'name': 'Woodcut_B0_S0_S30',
+    'embedded': {
+      'Stick_1_38940': {
+        'hash': 38940,
+        'name': 'Stick_1_38940',
+        'savables': {}
+      },
+      'Stick_2_38936': {
+        'hash': 38936,
+        'name': 'Stick_2_38936',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B0_S0_S60': {
+    'hash': 8102,
+    'name': 'Woodcut_B0_S0_S60',
+    'embedded': {
+      'Stick_1_38940': {
+        'hash': 38940,
+        'name': 'Stick_1',
+        'savables': {}
+      },
+      'Stick_2_38936': {
+        'hash': 38936,
+        'name': 'Stick_2',
+        'savables': {}
+      },
+      'Woodcut_B0_S0_S60_35622': {
+        'hash': 35622,
+        'name': 'Woodcut_B0_S0_S60',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_B0_S30_S30': {
+    'hash': 54764,
+    'name': 'Woodcut_B0_S30_S30',
+    'embedded': {
+      'Stick_1_38940': {
+        'hash': 38940,
+        'name': 'Stick_1',
+        'savables': {}
+      },
+      'Stick_2_38936': {
+        'hash': 38936,
+        'name': 'Stick_2',
+        'savables': {}
+      },
+      'Woodcut_B0_S30_S30_35622': {
+        'hash': 35622,
+        'name': 'Woodcut_B0_S30_S30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_B15_B15': {
+    'hash': 38016,
+    'name': 'Woodcut_B15_B15',
+    'embedded': {
+      'Top_4690': {
+        'hash': 4690,
+        'name': 'Top_4690',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B30_B30': {
+    'hash': 62548,
+    'name': 'Woodcut_B30_B30',
+    'embedded': {
+      'Top_58002': {
+        'hash': 58002,
+        'name': 'Top_58002',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_B5_B5': {
+    'hash': 1780,
+    'name': 'Woodcut_B5_B5',
+    'embedded': {
+      'Top_37822': {
+        'hash': 37822,
+        'name': 'Top_37822',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_Base': {
+    'hash': 37794,
+    'name': 'Woodcut_Birch_LeafClump_Base',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_Base_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Birch_LeafClump_Base',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C1_1': {
+    'hash': 1178,
+    'name': 'Woodcut_Birch_LeafClump_C1C1_1',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C1_1_1176': {
+        'hash': 1176,
+        'name': 'Woodcut_Birch_LeafClump_C1C1_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C1_1_E': {
+    'hash': 7260,
+    'name': 'Woodcut_Birch_LeafClump_C1C1_1_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C1_1_E_7258': {
+        'hash': 7258,
+        'name': 'Woodcut_Birch_LeafClump_C1C1_1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C1_2': {
+    'hash': 42598,
+    'name': 'Woodcut_Birch_LeafClump_C1C1_2',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C1_2_42596': {
+        'hash': 42596,
+        'name': 'Woodcut_Birch_LeafClump_C1C1_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C1_2_E': {
+    'hash': 10700,
+    'name': 'Woodcut_Birch_LeafClump_C1C1_2_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C1_2_E_10698': {
+        'hash': 10698,
+        'name': 'Woodcut_Birch_LeafClump_C1C1_2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C2_1': {
+    'hash': 54804,
+    'name': 'Woodcut_Birch_LeafClump_C1C2_1',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C2_1_54802': {
+        'hash': 54802,
+        'name': 'Woodcut_Birch_LeafClump_C1C2_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C2_1_E': {
+    'hash': 2760,
+    'name': 'Woodcut_Birch_LeafClump_C1C2_1_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C2_1_E_2758': {
+        'hash': 2758,
+        'name': 'Woodcut_Birch_LeafClump_C1C2_1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C2_2': {
+    'hash': 12688,
+    'name': 'Woodcut_Birch_LeafClump_C1C2_2',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C2_2_12686': {
+        'hash': 12686,
+        'name': 'Woodcut_Birch_LeafClump_C1C2_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1C2_2_E': {
+    'hash': 54174,
+    'name': 'Woodcut_Birch_LeafClump_C1C2_2_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1C2_2_E_54172': {
+        'hash': 54172,
+        'name': 'Woodcut_Birch_LeafClump_C1C2_2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C1_E': {
+    'hash': 55364,
+    'name': 'Woodcut_Birch_LeafClump_C1_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C1_E_55362': {
+        'hash': 55362,
+        'name': 'Woodcut_Birch_LeafClump_C1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C2C3_1': {
+    'hash': 54092,
+    'name': 'Woodcut_Birch_LeafClump_C2C3_1',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C2C3_1_54090': {
+        'hash': 54090,
+        'name': 'Woodcut_Birch_LeafClump_C2C3_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C2C3_1_E': {
+    'hash': 2568,
+    'name': 'Woodcut_Birch_LeafClump_C2C3_1_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C2C3_1_E_2566': {
+        'hash': 2566,
+        'name': 'Woodcut_Birch_LeafClump_C2C3_1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C2C3_2': {
+    'hash': 54852,
+    'name': 'Woodcut_Birch_LeafClump_C2C3_2',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C2C3_2_54850': {
+        'hash': 54850,
+        'name': 'Woodcut_Birch_LeafClump_C2C3_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C2C3_2_E': {
+    'hash': 54108,
+    'name': 'Woodcut_Birch_LeafClump_C2C3_2_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C2C3_2_E_54106': {
+        'hash': 54106,
+        'name': 'Woodcut_Birch_LeafClump_C2C3_2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C2_E': {
+    'hash': 12672,
+    'name': 'Woodcut_Birch_LeafClump_C2_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C2_E_12670': {
+        'hash': 12670,
+        'name': 'Woodcut_Birch_LeafClump_C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C3C4_1': {
+    'hash': 7276,
+    'name': 'Woodcut_Birch_LeafClump_C3C4_1',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C3C4_1_7274': {
+        'hash': 7274,
+        'name': 'Woodcut_Birch_LeafClump_C3C4_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C3C4_1_E': {
+    'hash': 34602,
+    'name': 'Woodcut_Birch_LeafClump_C3C4_1_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C3C4_1_E_34600': {
+        'hash': 34600,
+        'name': 'Woodcut_Birch_LeafClump_C3C4_1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C3C4_2': {
+    'hash': 12182,
+    'name': 'Woodcut_Birch_LeafClump_C3C4_2',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C3C4_2_12180': {
+        'hash': 12180,
+        'name': 'Woodcut_Birch_LeafClump_C3C4_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C3C4_2_E': {
+    'hash': 11234,
+    'name': 'Woodcut_Birch_LeafClump_C3C4_2_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C3C4_2_E_11232': {
+        'hash': 11232,
+        'name': 'Woodcut_Birch_LeafClump_C3C4_2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C3_E': {
+    'hash': 54820,
+    'name': 'Woodcut_Birch_LeafClump_C3_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C3_E_54818': {
+        'hash': 54818,
+        'name': 'Woodcut_Birch_LeafClump_C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_LeafClump_C4_E': {
+    'hash': 44404,
+    'name': 'Woodcut_Birch_LeafClump_C4_E',
+    'embedded': {
+      'Woodcut_Birch_LeafClump_C4_E_44402': {
+        'hash': 44402,
+        'name': 'Woodcut_Birch_LeafClump_C4_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Birch_Seed_Spawner_Attachment': {
+    'hash': 16026,
+    'name': 'Woodcut_Birch_Seed_Spawner_Attachment',
+    'embedded': {
+      'Woodcut_Birch_Seed_Spawner_Attachment_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Birch_Seed_Spawner_Attachment',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_BranchRoot_V1_B0': {
+    'hash': 8158,
+    'name': 'Woodcut_BranchRoot_V1_B0',
+    'embedded': {
+      'Top_14282': {
+        'hash': 14282,
+        'name': 'Top_14282',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_BranchRoot_V1_B15_S30': {
+    'hash': 22660,
+    'name': 'Woodcut_BranchRoot_V1_B15_S30',
+    'embedded': {
+      'Top_63620': {
+        'hash': 63620,
+        'name': 'Top_63620',
+        'savables': {}
+      },
+      'Branch_63622': {
+        'hash': 63622,
+        'name': 'Branch_63622',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_BranchRoot_V2_B0': {
+    'hash': 50658,
+    'name': 'Woodcut_BranchRoot_V2_B0',
+    'embedded': {
+      'Top_14282': {
+        'hash': 14282,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_BranchRoot_V2_B0_10678': {
+        'hash': 10678,
+        'name': 'Woodcut_BranchRoot_V2_B0',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Leaves_V1_L_F': {
+    'hash': 42932,
+    'name': 'Woodcut_Leaves_V1_L_F',
+    'embedded': {}
+  },
+  'Woodcut_Leaves_V1_L_S': {
+    'hash': 42928,
+    'name': 'Woodcut_Leaves_V1_L_S',
+    'embedded': {}
+  },
+  'Woodcut_Leaves_V1_S_F': {
+    'hash': 42934,
+    'name': 'Woodcut_Leaves_V1_S_F',
+    'embedded': {}
+  },
+  'Woodcut_Leaves_V1_S_S': {
+    'hash': 42930,
+    'name': 'Woodcut_Leaves_V1_S_S',
+    'embedded': {}
+  },
+  'Woodcut_Leaves_V2_D': {
+    'hash': 63786,
+    'name': 'Woodcut_Leaves_V2_D',
+    'embedded': {}
+  },
+  'Woodcut_Leaves_V2_L': {
+    'hash': 63466,
+    'name': 'Woodcut_Leaves_V2_L',
+    'embedded': {}
+  },
+  'Woodcut_Leaves_V2_Topper': {
+    'hash': 26276,
+    'name': 'Woodcut_Leaves_V2_Topper',
+    'embedded': {}
+  },
+  'Woodcut_Oak_LeafClump_Base': {
+    'hash': 60158,
+    'name': 'Woodcut_Oak_LeafClump_Base',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_Base_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Oak_LeafClump_Base',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C1C1_1': {
+    'hash': 38364,
+    'name': 'Woodcut_Oak_LeafClump_C1C1_1',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C1C1_1_38362': {
+        'hash': 38362,
+        'name': 'Woodcut_Oak_LeafClump_C1C1_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C1C1_2': {
+    'hash': 38344,
+    'name': 'Woodcut_Oak_LeafClump_C1C1_2',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C1C1_2_38342': {
+        'hash': 38342,
+        'name': 'Woodcut_Oak_LeafClump_C1C1_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C1C2_1': {
+    'hash': 38324,
+    'name': 'Woodcut_Oak_LeafClump_C1C2_1',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C1C2_1_38322': {
+        'hash': 38322,
+        'name': 'Woodcut_Oak_LeafClump_C1C2_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C1C2_2': {
+    'hash': 38304,
+    'name': 'Woodcut_Oak_LeafClump_C1C2_2',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C1C2_2_38302': {
+        'hash': 38302,
+        'name': 'Woodcut_Oak_LeafClump_C1C2_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C1C2_E': {
+    'hash': 38284,
+    'name': 'Woodcut_Oak_LeafClump_C1C2_E',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C1C2_E_38282': {
+        'hash': 38282,
+        'name': 'Woodcut_Oak_LeafClump_C1C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C1_E': {
+    'hash': 38382,
+    'name': 'Woodcut_Oak_LeafClump_C1_E',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C1_E_38380': {
+        'hash': 38380,
+        'name': 'Woodcut_Oak_LeafClump_C1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C2C2_1': {
+    'hash': 38242,
+    'name': 'Woodcut_Oak_LeafClump_C2C2_1',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C2C2_1_38240': {
+        'hash': 38240,
+        'name': 'Woodcut_Oak_LeafClump_C2C2_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C2C2_2': {
+    'hash': 38224,
+    'name': 'Woodcut_Oak_LeafClump_C2C2_2',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C2C2_2_38222': {
+        'hash': 38222,
+        'name': 'Woodcut_Oak_LeafClump_C2C2_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C2C3_1': {
+    'hash': 38204,
+    'name': 'Woodcut_Oak_LeafClump_C2C3_1',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C2C3_1_38202': {
+        'hash': 38202,
+        'name': 'Woodcut_Oak_LeafClump_C2C3_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C2C3_2': {
+    'hash': 38184,
+    'name': 'Woodcut_Oak_LeafClump_C2C3_2',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C2C3_2_38182': {
+        'hash': 38182,
+        'name': 'Woodcut_Oak_LeafClump_C2C3_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C2C3_E': {
+    'hash': 38162,
+    'name': 'Woodcut_Oak_LeafClump_C2C3_E',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C2C3_E_38160': {
+        'hash': 38160,
+        'name': 'Woodcut_Oak_LeafClump_C2C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C2_E': {
+    'hash': 38264,
+    'name': 'Woodcut_Oak_LeafClump_C2_E',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C2_E_38262': {
+        'hash': 38262,
+        'name': 'Woodcut_Oak_LeafClump_C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C3C3_1': {
+    'hash': 38122,
+    'name': 'Woodcut_Oak_LeafClump_C3C3_1',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C3C3_1_38120': {
+        'hash': 38120,
+        'name': 'Woodcut_Oak_LeafClump_C3C3_1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C3C3_2': {
+    'hash': 38102,
+    'name': 'Woodcut_Oak_LeafClump_C3C3_2',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C3C3_2_38100': {
+        'hash': 38100,
+        'name': 'Woodcut_Oak_LeafClump_C3C3_2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_LeafClump_C3_E': {
+    'hash': 38144,
+    'name': 'Woodcut_Oak_LeafClump_C3_E',
+    'embedded': {
+      'Woodcut_Oak_LeafClump_C3_E_38142': {
+        'hash': 38142,
+        'name': 'Woodcut_Oak_LeafClump_C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Oak_Seed_Spawner_Attachment': {
+    'hash': 49710,
+    'name': 'Woodcut_Oak_Seed_Spawner_Attachment',
+    'embedded': {
+      'Woodcut_Oak_Seed_Spawner_Attachment_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Oak_Seed_Spawner_Attachment',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_Base': {
+    'hash': 55152,
+    'name': 'Woodcut_Redwood_LeafClump_Base',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_Base_55166': {
+        'hash': 55166,
+        'name': 'Woodcut_Redwood_LeafClump_Base',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T1_D30_C1C2': {
+    'hash': 21374,
+    'name': 'Woodcut_Redwood_LeafClump_T1_D30_C1C2',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T1_D30_C1C2_21372': {
+        'hash': 21372,
+        'name': 'Woodcut_Redwood_LeafClump_T1_D30_C1C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T1_D30_C3C4': {
+    'hash': 49074,
+    'name': 'Woodcut_Redwood_LeafClump_T1_D30_C3C4',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T1_D30_C3C4_49072': {
+        'hash': 49072,
+        'name': 'Woodcut_Redwood_LeafClump_T1_D30_C3C4',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T1_D30_C5C6': {
+    'hash': 55378,
+    'name': 'Woodcut_Redwood_LeafClump_T1_D30_C5C6',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T1_D30_C5C6_55376': {
+        'hash': 55376,
+        'name': 'Woodcut_Redwood_LeafClump_T1_D30_C5C6',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T1_D30_C7C8': {
+    'hash': 47486,
+    'name': 'Woodcut_Redwood_LeafClump_T1_D30_C7C8',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T1_D30_C7C8_47484': {
+        'hash': 47484,
+        'name': 'Woodcut_Redwood_LeafClump_T1_D30_C7C8',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T2_D30_C1C2': {
+    'hash': 55954,
+    'name': 'Woodcut_Redwood_LeafClump_T2_D30_C1C2',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T2_D30_C1C2_55952': {
+        'hash': 55952,
+        'name': 'Woodcut_Redwood_LeafClump_T2_D30_C1C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T2_D30_C3C4': {
+    'hash': 57266,
+    'name': 'Woodcut_Redwood_LeafClump_T2_D30_C3C4',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T2_D30_C3C4_57264': {
+        'hash': 57264,
+        'name': 'Woodcut_Redwood_LeafClump_T2_D30_C3C4',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T2_D30_C5C6': {
+    'hash': 1528,
+    'name': 'Woodcut_Redwood_LeafClump_T2_D30_C5C6',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T2_D30_C5C6_1526': {
+        'hash': 1526,
+        'name': 'Woodcut_Redwood_LeafClump_T2_D30_C5C6',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T2_D30_C7C8': {
+    'hash': 9410,
+    'name': 'Woodcut_Redwood_LeafClump_T2_D30_C7C8',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T2_D30_C7C8_9408': {
+        'hash': 9408,
+        'name': 'Woodcut_Redwood_LeafClump_T2_D30_C7C8',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T3_D30_C1C2': {
+    'hash': 10666,
+    'name': 'Woodcut_Redwood_LeafClump_T3_D30_C1C2',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T3_D30_C1C2_10664': {
+        'hash': 10664,
+        'name': 'Woodcut_Redwood_LeafClump_T3_D30_C1C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T3_D30_C3C4': {
+    'hash': 6716,
+    'name': 'Woodcut_Redwood_LeafClump_T3_D30_C3C4',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T3_D30_C3C4_6714': {
+        'hash': 6714,
+        'name': 'Woodcut_Redwood_LeafClump_T3_D30_C3C4',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T3_D30_C5C6': {
+    'hash': 55520,
+    'name': 'Woodcut_Redwood_LeafClump_T3_D30_C5C6',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T3_D30_C5C6_55518': {
+        'hash': 55518,
+        'name': 'Woodcut_Redwood_LeafClump_T3_D30_C5C6',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T3_D30_C7C8': {
+    'hash': 6732,
+    'name': 'Woodcut_Redwood_LeafClump_T3_D30_C7C8',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T3_D30_C7C8_6730': {
+        'hash': 6730,
+        'name': 'Woodcut_Redwood_LeafClump_T3_D30_C7C8',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C1': {
+    'hash': 42552,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C1',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C1_44634': {
+        'hash': 44634,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C2': {
+    'hash': 46726,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C2',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C2_46724': {
+        'hash': 46724,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C3': {
+    'hash': 1774,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C3',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C3_1772': {
+        'hash': 1772,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C3',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C4': {
+    'hash': 1512,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C4',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C4_1510': {
+        'hash': 1510,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C4',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C5': {
+    'hash': 54122,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C5',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C5_54120': {
+        'hash': 54120,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C5',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C6': {
+    'hash': 7242,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C6',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C6_7240': {
+        'hash': 7240,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C6',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C7': {
+    'hash': 44386,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C7',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C7_44384': {
+        'hash': 44384,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C7',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafClump_T4_D30_C8': {
+    'hash': 10754,
+    'name': 'Woodcut_Redwood_LeafClump_T4_D30_C8',
+    'embedded': {
+      'Woodcut_Redwood_LeafClump_T4_D30_C8_10752': {
+        'hash': 10752,
+        'name': 'Woodcut_Redwood_LeafClump_T4_D30_C8',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_LeafTopper': {
+    'hash': 34724,
+    'name': 'Woodcut_Redwood_LeafTopper',
+    'embedded': {
+      'Woodcut_Redwood_LeafTopper_34720': {
+        'hash': 34720,
+        'name': 'Woodcut_Redwood_LeafTopper',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Redwood_Seed_Spawner_Attachment': {
+    'hash': 16012,
+    'name': 'Woodcut_Redwood_Seed_Spawner_Attachment',
+    'embedded': {
+      'Woodcut_Redwood_Seed_Spawner_Attachment_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Redwood_Seed_Spawner_Attachment',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Root_V1_T0': {
+    'hash': 31522,
+    'name': 'Woodcut_Root_V1_T0',
+    'embedded': {
+      'Top_49314': {
+        'hash': 49314,
+        'name': 'Top_49314',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Root_V1_T0_B15': {
+    'hash': 34660,
+    'name': 'Woodcut_Root_V1_T0_B15',
+    'embedded': {
+      'Top_23584': {
+        'hash': 23584,
+        'name': 'Top_23584',
+        'savables': {}
+      },
+      'Branch_12832': {
+        'hash': 12832,
+        'name': 'Branch_12832',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Root_V1_T0_S30': {
+    'hash': 34546,
+    'name': 'Woodcut_Root_V1_T0_S30',
+    'embedded': {
+      'Top_56452': {
+        'hash': 56452,
+        'name': 'Top_56452',
+        'savables': {}
+      },
+      'Stick_51558': {
+        'hash': 51558,
+        'name': 'Stick_51558',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Root_V1_T30': {
+    'hash': 47612,
+    'name': 'Woodcut_Root_V1_T30',
+    'embedded': {
+      'Top_7658': {
+        'hash': 7658,
+        'name': 'Top_7658',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_S-15_S-15': {
+    'hash': 39282,
+    'name': 'Woodcut_S-15_S-15',
+    'embedded': {
+      'Top_1286': {
+        'hash': 1286,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_S-15_S-15_45390': {
+        'hash': 45390,
+        'name': 'Woodcut_S-15_S-15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_S0_E': {
+    'hash': 25704,
+    'name': 'Woodcut_S0_E',
+    'embedded': {}
+  },
+  'Woodcut_S0_S0': {
+    'hash': 44986,
+    'name': 'Woodcut_S0_S0',
+    'embedded': {
+      'Top_1286': {
+        'hash': 1286,
+        'name': 'Top_1286',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_S0_S0_S-30': {
+    'hash': 25116,
+    'name': 'Woodcut_S0_S0_S-30',
+    'embedded': {
+      'Top_1_2062': {
+        'hash': 2062,
+        'name': 'Top_1',
+        'savables': {}
+      },
+      'Top_2_60778': {
+        'hash': 60778,
+        'name': 'Top_2',
+        'savables': {}
+      },
+      'Woodcut_S0_S0_S-30_64064': {
+        'hash': 64064,
+        'name': 'Woodcut_S0_S0_S-30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_S0_S0_S30': {
+    'hash': 190,
+    'name': 'Woodcut_S0_S0_S30',
+    'embedded': {
+      'Top_1_2062': {
+        'hash': 2062,
+        'name': 'Top_1',
+        'savables': {}
+      },
+      'Top_2_60778': {
+        'hash': 60778,
+        'name': 'Top_2',
+        'savables': {}
+      },
+      'Woodcut_S0_S0_S30_64064': {
+        'hash': 64064,
+        'name': 'Woodcut_S0_S0_S30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_S0_S15_S15': {
+    'hash': 62106,
+    'name': 'Woodcut_S0_S15_S15',
+    'embedded': {
+      'Top_1_2062': {
+        'hash': 2062,
+        'name': 'Top_1_2062',
+        'savables': {}
+      },
+      'Top_2_60778': {
+        'hash': 60778,
+        'name': 'Top_2_60778',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_S0_S30_S30': {
+    'hash': 9058,
+    'name': 'Woodcut_S0_S30_S30',
+    'embedded': {
+      'Top_1_9064': {
+        'hash': 9064,
+        'name': 'Top_1',
+        'savables': {}
+      },
+      'Top_2_9062': {
+        'hash': 9062,
+        'name': 'Top_2',
+        'savables': {}
+      },
+      'Woodcut_S0_S30_S30_9060': {
+        'hash': 9060,
+        'name': 'Woodcut_S0_S30_S30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_S15_S15': {
+    'hash': 19364,
+    'name': 'Woodcut_S15_S15',
+    'embedded': {
+      'Top_1286': {
+        'hash': 1286,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_S15_S15_45390': {
+        'hash': 45390,
+        'name': 'Woodcut_S15_S15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_SL15_SL15': {
+    'hash': 7464,
+    'name': 'Woodcut_SL15_SL15',
+    'embedded': {
+      'Top_1286': {
+        'hash': 1286,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_SL15_SL15_7460': {
+        'hash': 7460,
+        'name': 'Woodcut_SL15_SL15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_SR15_SR15': {
+    'hash': 53266,
+    'name': 'Woodcut_SR15_SR15',
+    'embedded': {
+      'Top_1286': {
+        'hash': 1286,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_SR15_SR15_53262': {
+        'hash': 53262,
+        'name': 'Woodcut_SR15_SR15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_T0_B0_B30': {
+    'hash': 35026,
+    'name': 'Woodcut_T0_B0_B30',
+    'embedded': {
+      'Branch_1_4000': {
+        'hash': 4000,
+        'name': 'Branch_1_4000',
+        'savables': {}
+      },
+      'Branch_2_3996': {
+        'hash': 3996,
+        'name': 'Branch_2_3996',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_B15_B30': {
+    'hash': 21794,
+    'name': 'Woodcut_T0_B15_B30',
+    'embedded': {
+      'Branch_1_634': {
+        'hash': 634,
+        'name': 'Branch_1_634',
+        'savables': {}
+      },
+      'Branch_2_636': {
+        'hash': 636,
+        'name': 'Branch_2_636',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_B30_B30': {
+    'hash': 26492,
+    'name': 'Woodcut_T0_B30_B30',
+    'embedded': {
+      'Branch_1_26494': {
+        'hash': 26494,
+        'name': 'Branch_1',
+        'savables': {}
+      },
+      'Branch_2_26488': {
+        'hash': 26488,
+        'name': 'Branch_2',
+        'savables': {}
+      },
+      'Woodcut_T0_B30_B30_26500': {
+        'hash': 26500,
+        'name': 'Woodcut_T0_B30_B30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_T0_B45_B45_B60': {
+    'hash': 62378,
+    'name': 'Woodcut_T0_B45_B45_B60',
+    'embedded': {
+      'Branch_1_4000': {
+        'hash': 4000,
+        'name': 'Branch_1',
+        'savables': {}
+      },
+      'Branch_2_20244': {
+        'hash': 20244,
+        'name': 'Branch_2',
+        'savables': {}
+      },
+      'Branch_3_20258': {
+        'hash': 20258,
+        'name': 'Branch_3',
+        'savables': {}
+      },
+      'Woodcut_T0_B45_B45_B60_35620': {
+        'hash': 35620,
+        'name': 'Woodcut_T0_B45_B45_B60',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_T0_E': {
+    'hash': 49440,
+    'name': 'Woodcut_T0_E',
+    'embedded': {}
+  },
+  'Woodcut_T0_T0': {
+    'hash': 6554,
+    'name': 'Woodcut_T0_T0',
+    'embedded': {
+      'Top_39100': {
+        'hash': 39100,
+        'name': 'Top_39100',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_T0_B30': {
+    'hash': 35016,
+    'name': 'Woodcut_T0_T0_B30',
+    'embedded': {
+      'Top_34360': {
+        'hash': 34360,
+        'name': 'Top_34360',
+        'savables': {}
+      },
+      'Branch_34356': {
+        'hash': 34356,
+        'name': 'Branch_34356',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_T0_B45': {
+    'hash': 52242,
+    'name': 'Woodcut_T0_T0_B45',
+    'embedded': {
+      'Top_15160': {
+        'hash': 15160,
+        'name': 'Top_15160',
+        'savables': {}
+      },
+      'Branch_15162': {
+        'hash': 15162,
+        'name': 'Branch_15162',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_T0_B45_B45_B60': {
+    'hash': 34502,
+    'name': 'Woodcut_T0_T0_B45_B45_B60',
+    'embedded': {
+      'Branch_1_15162': {
+        'hash': 15162,
+        'name': 'Branch_1',
+        'savables': {}
+      },
+      'Branch_2_19850': {
+        'hash': 19850,
+        'name': 'Branch_2',
+        'savables': {}
+      },
+      'Branch_3_19844': {
+        'hash': 19844,
+        'name': 'Branch_3',
+        'savables': {}
+      },
+      'Top_15160': {
+        'hash': 15160,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_T0_T0_B45_B45_B60_55228': {
+        'hash': 55228,
+        'name': 'Woodcut_T0_T0_B45_B45_B60',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_T0_T0_B60': {
+    'hash': 29162,
+    'name': 'Woodcut_T0_T0_B60',
+    'embedded': {
+      'Branch_15162': {
+        'hash': 15162,
+        'name': 'Branch',
+        'savables': {}
+      },
+      'Top_15160': {
+        'hash': 15160,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_T0_T0_B60_55228': {
+        'hash': 55228,
+        'name': 'Woodcut_T0_T0_B60',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_T0_T0_S30': {
+    'hash': 35022,
+    'name': 'Woodcut_T0_T0_S30',
+    'embedded': {
+      'Top_45916': {
+        'hash': 45916,
+        'name': 'Top_45916',
+        'savables': {}
+      },
+      'Stick_45912': {
+        'hash': 45912,
+        'name': 'Stick_45912',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_T0_S30_S30_S30': {
+    'hash': 33712,
+    'name': 'Woodcut_T0_T0_S30_S30_S30',
+    'embedded': {
+      'Top_836': {
+        'hash': 836,
+        'name': 'Top_836',
+        'savables': {}
+      },
+      'Stick_1_34724': {
+        'hash': 34724,
+        'name': 'Stick_1_34724',
+        'savables': {}
+      },
+      'Stick_2_17522': {
+        'hash': 17522,
+        'name': 'Stick_2_17522',
+        'savables': {}
+      },
+      'Stick_3_910': {
+        'hash': 910,
+        'name': 'Stick_3_910',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T0_T30_B30': {
+    'hash': 2712,
+    'name': 'Woodcut_T0_T30_B30',
+    'embedded': {
+      'Branch_15162': {
+        'hash': 15162,
+        'name': 'Branch',
+        'savables': {}
+      },
+      'Top_15160': {
+        'hash': 15160,
+        'name': 'Top',
+        'savables': {}
+      },
+      'Woodcut_T0_T30_B30_55228': {
+        'hash': 55228,
+        'name': 'Woodcut_T0_T30_B30',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_T15_T15': {
+    'hash': 40700,
+    'name': 'Woodcut_T15_T15',
+    'embedded': {
+      'Top_30734': {
+        'hash': 30734,
+        'name': 'Top_30734',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T30_T30': {
+    'hash': 30226,
+    'name': 'Woodcut_T30_T30',
+    'embedded': {
+      'Top_28372': {
+        'hash': 28372,
+        'name': 'Top_28372',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_T5_T5': {
+    'hash': 18498,
+    'name': 'Woodcut_T5_T5',
+    'embedded': {
+      'Top_32750': {
+        'hash': 32750,
+        'name': 'Top_32750',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Training_Block': {
+    'hash': 13392,
+    'name': 'Woodcut_Training_Block',
+    'embedded': {
+      'Woodcut_Training_Block_11246': {
+        'hash': 11246,
+        'name': 'Woodcut_Training_Block',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Twigs_V1_-30': {
+    'hash': 49360,
+    'name': 'Woodcut_Twigs_V1_-30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V1_0': {
+    'hash': 64824,
+    'name': 'Woodcut_Twigs_V1_0',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V1_30': {
+    'hash': 19674,
+    'name': 'Woodcut_Twigs_V1_30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V2_-30': {
+    'hash': 63554,
+    'name': 'Woodcut_Twigs_V2_-30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V2_0': {
+    'hash': 1846,
+    'name': 'Woodcut_Twigs_V2_0',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V2_30': {
+    'hash': 1452,
+    'name': 'Woodcut_Twigs_V2_30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V3_-30': {
+    'hash': 49972,
+    'name': 'Woodcut_Twigs_V3_-30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V3_0': {
+    'hash': 63168,
+    'name': 'Woodcut_Twigs_V3_0',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V3_30': {
+    'hash': 15084,
+    'name': 'Woodcut_Twigs_V3_30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V4_0': {
+    'hash': 52628,
+    'name': 'Woodcut_Twigs_V4_0',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V4_30': {
+    'hash': 31554,
+    'name': 'Woodcut_Twigs_V4_30',
+    'embedded': {}
+  },
+  'Woodcut_Twigs_V5_-15': {
+    'hash': 16424,
+    'name': 'Woodcut_Twigs_V5_-15',
+    'embedded': {
+      'Woodcut_Twigs_V5_-15_47386': {
+        'hash': 47386,
+        'name': 'Woodcut_Twigs_V5_-15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Twigs_V5_15': {
+    'hash': 32642,
+    'name': 'Woodcut_Twigs_V5_15',
+    'embedded': {
+      'Woodcut_Twigs_V5_15_32644': {
+        'hash': 32644,
+        'name': 'Woodcut_Twigs_V5_15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Twigs_V5_L15': {
+    'hash': 40208,
+    'name': 'Woodcut_Twigs_V5_L15',
+    'embedded': {
+      'Woodcut_Twigs_V5_L15_40210': {
+        'hash': 40210,
+        'name': 'Woodcut_Twigs_V5_L15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Twigs_V5_R15': {
+    'hash': 25388,
+    'name': 'Woodcut_Twigs_V5_R15',
+    'embedded': {
+      'Woodcut_Twigs_V5_R15_25390': {
+        'hash': 25390,
+        'name': 'Woodcut_Twigs_V5_R15',
+        'savables': {
+          'WoodcutPointCollection': {
+            'hash': 276353327,
+            'name': 'WoodcutPointCollection'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_Base': {
+    'hash': 47632,
+    'name': 'Woodcut_Walnut_LeafClump_Base',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_Base_47646': {
+        'hash': 47646,
+        'name': 'Woodcut_Walnut_LeafClump_Base',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C1C1': {
+    'hash': 29962,
+    'name': 'Woodcut_Walnut_LeafClump_C1C1',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C1C1_29960': {
+        'hash': 29960,
+        'name': 'Woodcut_Walnut_LeafClump_C1C1',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C1C1_E': {
+    'hash': 2796,
+    'name': 'Woodcut_Walnut_LeafClump_C1C1_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C1C1_E_2794': {
+        'hash': 2794,
+        'name': 'Woodcut_Walnut_LeafClump_C1C1_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C1C2': {
+    'hash': 8570,
+    'name': 'Woodcut_Walnut_LeafClump_C1C2',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C1C2_8568': {
+        'hash': 8568,
+        'name': 'Woodcut_Walnut_LeafClump_C1C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C1C2_E': {
+    'hash': 54836,
+    'name': 'Woodcut_Walnut_LeafClump_C1C2_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C1C2_E_54834': {
+        'hash': 54834,
+        'name': 'Woodcut_Walnut_LeafClump_C1C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C2C2': {
+    'hash': 8932,
+    'name': 'Woodcut_Walnut_LeafClump_C2C2',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C2C2_8930': {
+        'hash': 8930,
+        'name': 'Woodcut_Walnut_LeafClump_C2C2',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C2C2_E': {
+    'hash': 1792,
+    'name': 'Woodcut_Walnut_LeafClump_C2C2_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C2C2_E_1790': {
+        'hash': 1790,
+        'name': 'Woodcut_Walnut_LeafClump_C2C2_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C2C3': {
+    'hash': 47520,
+    'name': 'Woodcut_Walnut_LeafClump_C2C3',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C2C3_47518': {
+        'hash': 47518,
+        'name': 'Woodcut_Walnut_LeafClump_C2C3',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C2C3_E': {
+    'hash': 46292,
+    'name': 'Woodcut_Walnut_LeafClump_C2C3_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C2C3_E_46290': {
+        'hash': 46290,
+        'name': 'Woodcut_Walnut_LeafClump_C2C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C3C3': {
+    'hash': 54190,
+    'name': 'Woodcut_Walnut_LeafClump_C3C3',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C3C3_54188': {
+        'hash': 54188,
+        'name': 'Woodcut_Walnut_LeafClump_C3C3',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C3C3_E': {
+    'hash': 8292,
+    'name': 'Woodcut_Walnut_LeafClump_C3C3_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C3C3_E_8290': {
+        'hash': 8290,
+        'name': 'Woodcut_Walnut_LeafClump_C3C3_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C3C4': {
+    'hash': 57820,
+    'name': 'Woodcut_Walnut_LeafClump_C3C4',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C3C4_57818': {
+        'hash': 57818,
+        'name': 'Woodcut_Walnut_LeafClump_C3C4',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C3C4_E': {
+    'hash': 1546,
+    'name': 'Woodcut_Walnut_LeafClump_C3C4_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C3C4_E_1544': {
+        'hash': 1544,
+        'name': 'Woodcut_Walnut_LeafClump_C3C4_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C4C4_E': {
+    'hash': 44372,
+    'name': 'Woodcut_Walnut_LeafClump_C4C4_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C4C4_E_44370': {
+        'hash': 44370,
+        'name': 'Woodcut_Walnut_LeafClump_C4C4_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C4C5_E': {
+    'hash': 6218,
+    'name': 'Woodcut_Walnut_LeafClump_C4C5_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C4C5_E_6216': {
+        'hash': 6216,
+        'name': 'Woodcut_Walnut_LeafClump_C4C5_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_LeafClump_C5C5_E': {
+    'hash': 9940,
+    'name': 'Woodcut_Walnut_LeafClump_C5C5_E',
+    'embedded': {
+      'Woodcut_Walnut_LeafClump_C5C5_E_9938': {
+        'hash': 9938,
+        'name': 'Woodcut_Walnut_LeafClump_C5C5_E',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Walnut_Seed_Spawner_Attachment': {
+    'hash': 16040,
+    'name': 'Woodcut_Walnut_Seed_Spawner_Attachment',
+    'embedded': {
+      'Woodcut_Walnut_Seed_Spawner_Attachment_36402': {
+        'hash': 36402,
+        'name': 'Woodcut_Walnut_Seed_Spawner_Attachment',
+        'savables': {}
+      }
+    }
+  },
+  'Woodcut_Wedge': {
+    'hash': 47118,
+    'name': 'Woodcut_Wedge',
+    'embedded': {
+      'Woodcut_Wedge_10506': {
+        'hash': 10506,
+        'name': 'Woodcut_Wedge',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Wedge_Ashen': {
+    'hash': 232,
+    'name': 'Woodcut_Wedge_Ashen',
+    'embedded': {
+      'Woodcut_Wedge_Ashen_3674': {
+        'hash': 3674,
+        'name': 'Woodcut_Wedge_Ashen',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Wedge_Burnt': {
+    'hash': 290,
+    'name': 'Woodcut_Wedge_Burnt',
+    'embedded': {
+      'Woodcut_Wedge_Burnt_3674': {
+        'hash': 3674,
+        'name': 'Woodcut_Wedge_Burnt',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Wedge_Charred': {
+    'hash': 58068,
+    'name': 'Woodcut_Wedge_Charred',
+    'embedded': {
+      'Woodcut_Wedge_Charred_3674': {
+        'hash': 3674,
+        'name': 'Woodcut_Wedge_Charred',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Woodcut_Wedge_Storage': {
+    'hash': 12512,
+    'name': 'Woodcut_Wedge_Storage',
+    'embedded': {
+      'Filter_Dock_57214': {
+        'hash': 57214,
+        'name': 'Filter_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Interaction_Point_59032': {
+        'hash': 59032,
+        'name': 'Interaction_Point',
+        'savables': {}
+      },
+      'Internal_Dock_59328': {
+        'hash': 59328,
+        'name': 'Internal_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Withdraw_Dock_34750': {
+        'hash': 34750,
+        'name': 'Withdraw_Dock',
+        'savables': {}
+      },
+      'Woodcut_Wedge_Storage_12490': {
+        'hash': 12490,
+        'name': 'Woodcut_Wedge_Storage',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'CommunalStorage': {
+            'hash': 3084373371,
+            'name': 'CommunalStorage'
+          },
+          'PlayerInteractionRestrictor': {
+            'hash': 2951515968,
+            'name': 'PlayerInteractionRestrictor'
+          }
+        }
+      }
+    }
+  },
+  'Woodcutting_Path': {
+    'hash': 45418,
+    'name': 'Woodcutting_Path',
+    'embedded': {
+      'Woodcutting_Path_54368': {
+        'hash': 54368,
+        'name': 'Woodcutting_Path',
+        'savables': {
+          'PopulationPath': {
+            'hash': 7704646,
+            'name': 'PopulationPath'
+          }
+        }
+      }
+    }
+  },
+  'Woodcutting_Vines_V1_Large': {
+    'hash': 24682,
+    'name': 'Woodcutting_Vines_V1_Large',
+    'embedded': {}
+  },
+  'Woodcutting_Vines_V1_Small_V1': {
+    'hash': 24686,
+    'name': 'Woodcutting_Vines_V1_Small_V1',
+    'embedded': {}
+  },
+  'Woodcutting_Vines_V1_Small_V2': {
+    'hash': 24684,
+    'name': 'Woodcutting_Vines_V1_Small_V2',
+    'embedded': {}
+  },
+  'Woodcutting_Vines_V1_Small_V3': {
+    'hash': 24688,
+    'name': 'Woodcutting_Vines_V1_Small_V3',
+    'embedded': {}
+  },
+  'Wooden_Bag': {
+    'hash': 30060,
+    'name': 'Wooden_Bag',
+    'embedded': {
+      'Bag_Body_42972': {
+        'hash': 42972,
+        'name': 'Bag_Body',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      },
+      'Dock_ML_42984': {
+        'hash': 42984,
+        'name': 'Dock_ML',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MM_42982': {
+        'hash': 42982,
+        'name': 'Dock_MM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_MR_42980': {
+        'hash': 42980,
+        'name': 'Dock_MR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TL_42990': {
+        'hash': 42990,
+        'name': 'Dock_TL',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TM_42988': {
+        'hash': 42988,
+        'name': 'Dock_TM',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Dock_TR_42986': {
+        'hash': 42986,
+        'name': 'Dock_TR',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Wooden_Bag_43012': {
+        'hash': 43012,
+        'name': 'Wooden_Bag',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'wooden_bag_back_straw_22280': {
+        'hash': 22280,
+        'name': 'wooden_bag_back_straw',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_01_22276': {
+        'hash': 22276,
+        'name': 'wooden_bag_beam_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_02_22320': {
+        'hash': 22320,
+        'name': 'wooden_bag_beam_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_03_22316': {
+        'hash': 22316,
+        'name': 'wooden_bag_beam_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_04_22308': {
+        'hash': 22308,
+        'name': 'wooden_bag_beam_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_05_22304': {
+        'hash': 22304,
+        'name': 'wooden_bag_beam_05',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_06_22300': {
+        'hash': 22300,
+        'name': 'wooden_bag_beam_06',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_07_22296': {
+        'hash': 22296,
+        'name': 'wooden_bag_beam_07',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_curved_01_22292': {
+        'hash': 22292,
+        'name': 'wooden_bag_beam_curved_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_beam_curved_02_22288': {
+        'hash': 22288,
+        'name': 'wooden_bag_beam_curved_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_front_straw_22284': {
+        'hash': 22284,
+        'name': 'wooden_bag_front_straw',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_handle_738': {
+        'hash': 738,
+        'name': 'wooden_bag_handle',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_handle_wraps_742': {
+        'hash': 742,
+        'name': 'wooden_bag_handle_wraps',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_lid_straw_22312': {
+        'hash': 22312,
+        'name': 'wooden_bag_lid_straw',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_side_01_straw_22272': {
+        'hash': 22272,
+        'name': 'wooden_bag_side_01_straw',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'wooden_bag_side_02_straw_22268': {
+        'hash': 22268,
+        'name': 'wooden_bag_side_02_straw',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Barrel': {
+    'hash': 5890,
+    'name': 'Wooden_Barrel',
+    'embedded': {
+      'Handle_Pickup_13422': {
+        'hash': 13422,
+        'name': 'Handle_Pickup',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          }
+        }
+      },
+      'Handle__58484': {
+        'hash': 58484,
+        'name': 'Handle_',
+        'savables': {}
+      },
+      'Wooden_Barrel_11132': {
+        'hash': 11132,
+        'name': 'Wooden_Barrel',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          },
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Bowl': {
+    'hash': 25908,
+    'name': 'Wooden_Bowl',
+    'embedded': {
+      'Wooden_Bowl_23250': {
+        'hash': 23250,
+        'name': 'Wooden_Bowl',
+        'savables': {
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Bucket': {
+    'hash': 63904,
+    'name': 'Wooden_Bucket',
+    'embedded': {
+      'Bucket_Wooden_Metal_Bottom_20258': {
+        'hash': 20258,
+        'name': 'Bucket_Wooden_Metal_Bottom',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Bucket_Wooden_Metal_Top_20246': {
+        'hash': 20246,
+        'name': 'Bucket_Wooden_Metal_Top',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Bucket_Wooden_Wood_20270': {
+        'hash': 20270,
+        'name': 'Bucket_Wooden_Wood',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Bucket_Wooden_Wood_Bottom_20262': {
+        'hash': 20262,
+        'name': 'Bucket_Wooden_Wood_Bottom',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Handle_L__20254': {
+        'hash': 20254,
+        'name': 'Handle_L_',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Handle_R_20266': {
+        'hash': 20266,
+        'name': 'Handle_R',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Handle_Top_20250': {
+        'hash': 20250,
+        'name': 'Handle_Top',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'Heat_47560': {
+        'hash': 47560,
+        'name': 'Heat',
+        'savables': {
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'Wooden_Bucket_65316': {
+        'hash': 65316,
+        'name': 'Wooden_Bucket',
+        'savables': {
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          },
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'cookingPot_plate_01_24': {
+        'hash': 24,
+        'name': 'cookingPot_plate_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_02_28': {
+        'hash': 28,
+        'name': 'cookingPot_plate_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_03_36': {
+        'hash': 36,
+        'name': 'cookingPot_plate_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_04_32': {
+        'hash': 32,
+        'name': 'cookingPot_plate_04',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_mid_01_48': {
+        'hash': 48,
+        'name': 'cookingPot_plate_mid_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'cookingPot_plate_mid_02_56': {
+        'hash': 56,
+        'name': 'cookingPot_plate_mid_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Dice': {
+    'hash': 45608,
+    'name': 'Wooden_Dice',
+    'embedded': {
+      'Wooden_Dice_45490': {
+        'hash': 45490,
+        'name': 'Wooden_Dice',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Ladle': {
+    'hash': 15274,
+    'name': 'Wooden_Ladle',
+    'embedded': {
+      'Wooden_Ladle_16772': {
+        'hash': 16772,
+        'name': 'Wooden_Ladle',
+        'savables': {
+          'LiquidContainer': {
+            'hash': 4179293747,
+            'name': 'LiquidContainer'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Net': {
+    'hash': 53540,
+    'name': 'Wooden_Net',
+    'embedded': {
+      'Dock_42390': {
+        'hash': 42390,
+        'name': 'Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'Insert_HammerType_End_Cap_7796': {
+        'hash': 7796,
+        'name': 'Insert_HammerType_End_Cap',
+        'savables': {}
+      },
+      'Wooden_Net_7480': {
+        'hash': 7480,
+        'name': 'Wooden_Net',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      },
+      'woodenNet_basket_17034': {
+        'hash': 17034,
+        'name': 'woodenNet_basket',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'woodenNet_curvedFrame_01_17018': {
+        'hash': 17018,
+        'name': 'woodenNet_curvedFrame_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'woodenNet_curvedFrame_brace_01_17022': {
+        'hash': 17022,
+        'name': 'woodenNet_curvedFrame_brace_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'woodenNet_handle_01_17026': {
+        'hash': 17026,
+        'name': 'woodenNet_handle_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'woodenNet_knot_01_17038': {
+        'hash': 17038,
+        'name': 'woodenNet_knot_01',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'woodenNet_knot_02_17030': {
+        'hash': 17030,
+        'name': 'woodenNet_knot_02',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      },
+      'woodenNet_knot_03_17014': {
+        'hash': 17014,
+        'name': 'woodenNet_knot_03',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Passage_Dynamic': {
+    'hash': 43806,
+    'name': 'Wooden_Passage_Dynamic',
+    'embedded': {
+      'Enemy_Spawn_28160': {
+        'hash': 28160,
+        'name': 'Enemy_Spawn',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'Spawn_43748': {
+        'hash': 43748,
+        'name': 'Spawn',
+        'savables': {
+          'DirectionalBoundsSurface': {
+            'hash': 1962842866,
+            'name': 'DirectionalBoundsSurface'
+          },
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          }
+        }
+      },
+      'Wooden_Passage_Dynamic_43790': {
+        'hash': 43790,
+        'name': 'Wooden_Passage_Dynamic',
+        'savables': {}
+      }
+    }
+  },
+  'Wooden_Short_Sword': {
+    'hash': 16448,
+    'name': 'Wooden_Short_Sword',
+    'embedded': {
+      'Wooden_Short_Sword_18792': {
+        'hash': 18792,
+        'name': 'Wooden_Short_Sword',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Stake': {
+    'hash': 17262,
+    'name': 'Wooden_Stake',
+    'embedded': {
+      'Slot_Multi_11474': {
+        'hash': 11474,
+        'name': 'Slot_Multi',
+        'savables': {}
+      },
+      'Wooden_Stake_17052': {
+        'hash': 17052,
+        'name': 'Wooden_Stake',
+        'savables': {
+          'DurabilityModule': {
+            'hash': 1871432223,
+            'name': 'DurabilityModule'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'Wooden_Stirring_Spoon': {
+    'hash': 23950,
+    'name': 'Wooden_Stirring_Spoon',
+    'embedded': {
+      'Wooden_Stirring_Spoon_26366': {
+        'hash': 26366,
+        'name': 'Wooden_Stirring_Spoon',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'Wyrm': {
+    'hash': 21642,
+    'name': 'Wyrm',
+    'embedded': {
+      'Animation_6144': {
+        'hash': 6144,
+        'name': 'Animation',
+        'savables': {}
+      },
+      'Body_1052': {
+        'hash': 1052,
+        'name': 'Body',
+        'savables': {}
+      },
+      'Gameplay_42330': {
+        'hash': 42330,
+        'name': 'Gameplay',
+        'savables': {}
+      },
+      'Ground_58968': {
+        'hash': 58968,
+        'name': 'Ground',
+        'savables': {}
+      },
+      'SlashDamage_L_57358': {
+        'hash': 57358,
+        'name': 'SlashDamage_L',
+        'savables': {}
+      },
+      'SlashDamage_R_59218': {
+        'hash': 59218,
+        'name': 'SlashDamage_R',
+        'savables': {}
+      },
+      'Spawner_240': {
+        'hash': 240,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'Wyrm_37044': {
+        'hash': 37044,
+        'name': 'Wyrm',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Wyrm_AI_46146': {
+        'hash': 46146,
+        'name': 'Wyrm_AI',
+        'savables': {}
+      },
+      'scythe_l_jnt_544': {
+        'hash': 544,
+        'name': 'scythe_l_jnt',
+        'savables': {}
+      },
+      'scythe_r_jnt_542': {
+        'hash': 542,
+        'name': 'scythe_r_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Wyrm_(Trial)': {
+    'hash': 6004,
+    'name': 'Wyrm_(Trial)',
+    'embedded': {
+      'Animation_6144': {
+        'hash': 6144,
+        'name': 'Animation',
+        'savables': {}
+      },
+      'Body_1052': {
+        'hash': 1052,
+        'name': 'Body',
+        'savables': {}
+      },
+      'Gameplay_42330': {
+        'hash': 42330,
+        'name': 'Gameplay',
+        'savables': {}
+      },
+      'Ground_58968': {
+        'hash': 58968,
+        'name': 'Ground',
+        'savables': {}
+      },
+      'SlashDamage_L_57358': {
+        'hash': 57358,
+        'name': 'SlashDamage_L',
+        'savables': {}
+      },
+      'SlashDamage_R_59218': {
+        'hash': 59218,
+        'name': 'SlashDamage_R',
+        'savables': {}
+      },
+      'Spawner_240': {
+        'hash': 240,
+        'name': 'Spawner',
+        'savables': {}
+      },
+      'Wyrm_(Trial)_37044': {
+        'hash': 37044,
+        'name': 'Wyrm_(Trial)',
+        'savables': {
+          'PhysicalMaterialPart': {
+            'hash': 272188517,
+            'name': 'PhysicalMaterialPart'
+          },
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'Wyrm_AI_46146': {
+        'hash': 46146,
+        'name': 'Wyrm_AI',
+        'savables': {}
+      },
+      'scythe_l_jnt_544': {
+        'hash': 544,
+        'name': 'scythe_l_jnt',
+        'savables': {}
+      },
+      'scythe_r_jnt_542': {
+        'hash': 542,
+        'name': 'scythe_r_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'Wyrm_Arm': {
+    'hash': 46340,
+    'name': 'Wyrm_Arm',
+    'embedded': {}
+  },
+  'Wyrm_Boulder_01': {
+    'hash': 37174,
+    'name': 'Wyrm_Boulder_01',
+    'embedded': {
+      'Wyrm_Boulder_01_62528': {
+        'hash': 62528,
+        'name': 'Wyrm_Boulder_01',
+        'savables': {}
+      },
+      'Wyrm_Spawner_63404': {
+        'hash': 63404,
+        'name': 'Wyrm_Spawner',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      }
+    }
+  },
+  'Wyrm_Crystal_Spit': {
+    'hash': 37926,
+    'name': 'Wyrm_Crystal_Spit',
+    'embedded': {
+      'CrystalBall_62940': {
+        'hash': 62940,
+        'name': 'CrystalBall',
+        'savables': {}
+      },
+      'Wyrm_Crystal_Spit_62050': {
+        'hash': 62050,
+        'name': 'Wyrm_Crystal_Spit',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Wyrm_Spit': {
+    'hash': 61454,
+    'name': 'Wyrm_Spit',
+    'embedded': {
+      'PoisonBall_34058': {
+        'hash': 34058,
+        'name': 'PoisonBall',
+        'savables': {}
+      },
+      'Wyrm_Spit_62050': {
+        'hash': 62050,
+        'name': 'Wyrm_Spit',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          }
+        }
+      }
+    }
+  },
+  'Xnor': {
+    'hash': 42418,
+    'name': 'Xnor',
+    'embedded': {}
+  },
+  'Xor': {
+    'hash': 42428,
+    'name': 'Xor',
+    'embedded': {}
+  },
+  'archery_target_puzzle_test': {
+    'hash': 54358,
+    'name': 'archery_target_puzzle_test',
+    'embedded': {}
+  },
+  'cam': {
+    'hash': 8760,
+    'name': 'cam',
+    'embedded': {}
+  },
+  'combat_dummy': {
+    'hash': 57126,
+    'name': 'combat_dummy',
+    'embedded': {
+      'combat_dummy_57314': {
+        'hash': 57314,
+        'name': 'combat_dummy',
+        'savables': {
+          'StatManager': {
+            'hash': 2563567105,
+            'name': 'StatManager'
+          }
+        }
+      },
+      'dummy_arm_l_01_jnt_46272': {
+        'hash': 46272,
+        'name': 'dummy_arm_l_01_jnt',
+        'savables': {}
+      },
+      'dummy_arm_l_02_jnt_46248': {
+        'hash': 46248,
+        'name': 'dummy_arm_l_02_jnt',
+        'savables': {}
+      },
+      'dummy_arm_l_03_jnt_46250': {
+        'hash': 46250,
+        'name': 'dummy_arm_l_03_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_01_jnt_46246': {
+        'hash': 46246,
+        'name': 'dummy_arm_r_01_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_02_jnt_46254': {
+        'hash': 46254,
+        'name': 'dummy_arm_r_02_jnt',
+        'savables': {}
+      },
+      'dummy_arm_r_03_jnt_46256': {
+        'hash': 46256,
+        'name': 'dummy_arm_r_03_jnt',
+        'savables': {}
+      },
+      'dummy_head_01_jnt_46270': {
+        'hash': 46270,
+        'name': 'dummy_head_01_jnt',
+        'savables': {}
+      },
+      'dummy_head_02_jnt_46264': {
+        'hash': 46264,
+        'name': 'dummy_head_02_jnt',
+        'savables': {}
+      },
+      'dummy_head_03_jnt_46262': {
+        'hash': 46262,
+        'name': 'dummy_head_03_jnt',
+        'savables': {}
+      },
+      'dummy_neck_jnt_46268': {
+        'hash': 46268,
+        'name': 'dummy_neck_jnt',
+        'savables': {}
+      },
+      'dummy_spineMid_jnt_46274': {
+        'hash': 46274,
+        'name': 'dummy_spineMid_jnt',
+        'savables': {}
+      },
+      'dummy_spine_01_jnt_46258': {
+        'hash': 46258,
+        'name': 'dummy_spine_01_jnt',
+        'savables': {}
+      },
+      'dummy_spine_02_jnt_46260': {
+        'hash': 46260,
+        'name': 'dummy_spine_02_jnt',
+        'savables': {}
+      },
+      'dummy_spine_03_jnt_46266': {
+        'hash': 46266,
+        'name': 'dummy_spine_03_jnt',
+        'savables': {}
+      },
+      'dummy_sternum_jnt_46252': {
+        'hash': 46252,
+        'name': 'dummy_sternum_jnt',
+        'savables': {}
+      }
+    }
+  },
+  'item_pedestal_puzzle_base': {
+    'hash': 27250,
+    'name': 'item_pedestal_puzzle_base',
+    'embedded': {
+      'Pedestal_Dock_27002': {
+        'hash': 27002,
+        'name': 'Pedestal_Dock',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          },
+          'PickupDockPedestalSpawn': {
+            'hash': 2592242915,
+            'name': 'PickupDockPedestalSpawn'
+          }
+        }
+      },
+      'item_pedestal_puzzle_base_27194': {
+        'hash': 27194,
+        'name': 'item_pedestal_puzzle_base',
+        'savables': {
+          'LogicBoolSender': {
+            'hash': 1257282635,
+            'name': 'LogicBoolSender'
+          },
+          'LogicIntSender': {
+            'hash': 2880587164,
+            'name': 'LogicIntSender'
+          },
+          'PlaceItemPuzzleLogic': {
+            'hash': 1001395212,
+            'name': 'PlaceItemPuzzleLogic'
+          }
+        }
+      }
+    }
+  },
+  'mrk_extensionBridge_01': {
+    'hash': 34038,
+    'name': 'mrk_extensionBridge_01',
+    'embedded': {
+      'mrk_extensionBridge_01_32324': {
+        'hash': 32324,
+        'name': 'mrk_extensionBridge_01',
+        'savables': {
+          'LogicFloatReceiver': {
+            'hash': 3188272159,
+            'name': 'LogicFloatReceiver'
+          },
+          'NetworkedFloatStream': {
+            'hash': 2127962967,
+            'name': 'NetworkedFloatStream'
+          }
+        }
+      },
+      'mrk_extensionBridge_bridge_01_21508': {
+        'hash': 21508,
+        'name': 'mrk_extensionBridge_bridge_01',
+        'savables': {}
+      }
+    }
+  },
+  'mrk_large_lift_01': {
+    'hash': 28708,
+    'name': 'mrk_large_lift_01',
+    'embedded': {
+      'End_61234': {
+        'hash': 61234,
+        'name': 'End',
+        'savables': {}
+      },
+      'Start_1586': {
+        'hash': 1586,
+        'name': 'Start',
+        'savables': {}
+      },
+      'mrk_large_lift_01_49676': {
+        'hash': 49676,
+        'name': 'mrk_large_lift_01',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'mrk_lift_platform_41794': {
+        'hash': 41794,
+        'name': 'mrk_lift_platform',
+        'savables': {
+          'CurveOutput': {
+            'hash': 2576456808,
+            'name': 'CurveOutput'
+          }
+        }
+      }
+    }
+  },
+  'mrk_lift_01': {
+    'hash': 45646,
+    'name': 'mrk_lift_01',
+    'embedded': {
+      'Network_Event_1_10242': {
+        'hash': 10242,
+        'name': 'Network_Event_1',
+        'savables': {}
+      },
+      'Network_Event_2_10094': {
+        'hash': 10094,
+        'name': 'Network_Event_2',
+        'savables': {}
+      },
+      'Reset_Receiver_54952': {
+        'hash': 54952,
+        'name': 'Reset_Receiver',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'mrk_lift_01_49676': {
+        'hash': 49676,
+        'name': 'mrk_lift_01',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      },
+      'mrk_lift_platform_41794': {
+        'hash': 41794,
+        'name': 'mrk_lift_platform',
+        'savables': {
+          'CurveOutput': {
+            'hash': 2576456808,
+            'name': 'CurveOutput'
+          }
+        }
+      }
+    }
+  },
+  'mrk_puzzleCore_symbol_01': {
+    'hash': 48100,
+    'name': 'mrk_puzzleCore_symbol_01',
+    'embedded': {
+      'Glow_End_49116': {
+        'hash': 49116,
+        'name': 'Glow_End',
+        'savables': {}
+      },
+      'Glow_Start_40754': {
+        'hash': 40754,
+        'name': 'Glow_Start',
+        'savables': {}
+      },
+      'mrk_puzzleCore_symbol_01_4198': {
+        'hash': 4198,
+        'name': 'mrk_puzzleCore_symbol_01',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      }
+    }
+  },
+  'mrk_puzzleCore_symbol_02': {
+    'hash': 48102,
+    'name': 'mrk_puzzleCore_symbol_02',
+    'embedded': {
+      'Glow_End_39528': {
+        'hash': 39528,
+        'name': 'Glow_End',
+        'savables': {}
+      },
+      'Glow_Start_39856': {
+        'hash': 39856,
+        'name': 'Glow_Start',
+        'savables': {}
+      },
+      'mrk_puzzleCore_symbol_02_4422': {
+        'hash': 4422,
+        'name': 'mrk_puzzleCore_symbol_02',
+        'savables': {
+          'LogicBoolReceiver': {
+            'hash': 3751351177,
+            'name': 'LogicBoolReceiver'
+          }
+        }
+      }
+    }
+  },
+  'ore_copper': {
+    'hash': 22768,
+    'name': 'ore_copper',
+    'embedded': {}
+  },
+  'ore_gold': {
+    'hash': 38596,
+    'name': 'ore_gold',
+    'embedded': {}
+  },
+  'ore_iron': {
+    'hash': 60876,
+    'name': 'ore_iron',
+    'embedded': {}
+  },
+  'ore_mythril': {
+    'hash': 18158,
+    'name': 'ore_mythril',
+    'embedded': {}
+  },
+  'ore_silver': {
+    'hash': 26988,
+    'name': 'ore_silver',
+    'embedded': {}
+  },
+  'pot_01': {
+    'hash': 44028,
+    'name': 'pot_01',
+    'embedded': {}
+  },
+  'pumpkin_flower': {
+    'hash': 3116,
+    'name': 'pumpkin_flower',
+    'embedded': {
+      'pumpkin_flower_3100': {
+        'hash': 3100,
+        'name': 'pumpkin_flower',
+        'savables': {}
+      }
+    }
+  },
+  'pumpkin_full_burnt': {
+    'hash': 5532,
+    'name': 'pumpkin_full_burnt',
+    'embedded': {
+      'Cooking_29838': {
+        'hash': 29838,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_full_burnt_5096': {
+        'hash': 5096,
+        'name': 'pumpkin_full_burnt',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_full_cooked': {
+    'hash': 5010,
+    'name': 'pumpkin_full_cooked',
+    'embedded': {
+      'Cooking_29126': {
+        'hash': 29126,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_full_cooked_4574': {
+        'hash': 4574,
+        'name': 'pumpkin_full_cooked',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_full_ripe': {
+    'hash': 4488,
+    'name': 'pumpkin_full_ripe',
+    'embedded': {
+      'Chisel_Handler_32690': {
+        'hash': 32690,
+        'name': 'Chisel_Handler',
+        'savables': {}
+      },
+      'Cooking_28436': {
+        'hash': 28436,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_full_ripe_4052': {
+        'hash': 4052,
+        'name': 'pumpkin_full_ripe',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_full_unripe': {
+    'hash': 3966,
+    'name': 'pumpkin_full_unripe',
+    'embedded': {
+      'pumpkin_full_unripe_3530': {
+        'hash': 3530,
+        'name': 'pumpkin_full_unripe',
+        'savables': {
+          'MultiHandPickup': {
+            'hash': 1556697998,
+            'name': 'MultiHandPickup'
+          },
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_half_burnt': {
+    'hash': 3444,
+    'name': 'pumpkin_half_burnt',
+    'embedded': {
+      'Cooking_42504': {
+        'hash': 42504,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_half_burnt_3136': {
+        'hash': 3136,
+        'name': 'pumpkin_half_burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_half_cooked': {
+    'hash': 3082,
+    'name': 'pumpkin_half_cooked',
+    'embedded': {
+      'Cooking_41658': {
+        'hash': 41658,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_half_cooked_2774': {
+        'hash': 2774,
+        'name': 'pumpkin_half_cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_half_ripe': {
+    'hash': 2720,
+    'name': 'pumpkin_half_ripe',
+    'embedded': {
+      'Cooking_40786': {
+        'hash': 40786,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_half_ripe_2412': {
+        'hash': 2412,
+        'name': 'pumpkin_half_ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_half_unripe': {
+    'hash': 2358,
+    'name': 'pumpkin_half_unripe',
+    'embedded': {
+      'pumpkin_half_unripe_2050': {
+        'hash': 2050,
+        'name': 'pumpkin_half_unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_piece_burnt': {
+    'hash': 42218,
+    'name': 'pumpkin_piece_burnt',
+    'embedded': {
+      'Cooking_63858': {
+        'hash': 63858,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_piece_burnt_41976': {
+        'hash': 41976,
+        'name': 'pumpkin_piece_burnt',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_piece_cooked': {
+    'hash': 41930,
+    'name': 'pumpkin_piece_cooked',
+    'embedded': {
+      'Cooking_65232': {
+        'hash': 65232,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_piece_cooked_41654': {
+        'hash': 41654,
+        'name': 'pumpkin_piece_cooked',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_piece_ripe': {
+    'hash': 41608,
+    'name': 'pumpkin_piece_ripe',
+    'embedded': {
+      'Cooking_26172': {
+        'hash': 26172,
+        'name': 'Cooking',
+        'savables': {
+          'Cookable': {
+            'hash': 205333986,
+            'name': 'Cookable'
+          },
+          'HeatPointCollection': {
+            'hash': 1217391130,
+            'name': 'HeatPointCollection'
+          }
+        }
+      },
+      'pumpkin_piece_ripe_41332': {
+        'hash': 41332,
+        'name': 'pumpkin_piece_ripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          }
+        }
+      }
+    }
+  },
+  'pumpkin_piece_unripe': {
+    'hash': 41286,
+    'name': 'pumpkin_piece_unripe',
+    'embedded': {
+      'pumpkin_piece_unripe_41010': {
+        'hash': 41010,
+        'name': 'pumpkin_piece_unripe',
+        'savables': {
+          'NetworkRigidbody': {
+            'hash': 2290978823,
+            'name': 'NetworkRigidbody'
+          },
+          'Pickup': {
+            'hash': 1454441398,
+            'name': 'Pickup'
+          },
+          'PickupDecay': {
+            'hash': 2807522140,
+            'name': 'PickupDecay'
+          },
+          'RaycastCrafter': {
+            'hash': 2815374842,
+            'name': 'RaycastCrafter'
+          }
+        }
+      }
+    }
+  },
+  'ruins_orbBasin_01': {
+    'hash': 27482,
+    'name': 'ruins_orbBasin_01',
+    'embedded': {
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {
+          'AddUnlockToPlayer': {
+            'hash': 1756836969,
+            'name': 'AddUnlockToPlayer'
+          },
+          'OrbBasinVfxController': {
+            'hash': 715394364,
+            'name': 'OrbBasinVfxController'
+          },
+          'PlayerUnlockStation': {
+            'hash': 2912807649,
+            'name': 'PlayerUnlockStation'
+          }
+        }
+      },
+      'ruins_orbBasin_01_24754': {
+        'hash': 24754,
+        'name': 'ruins_orbBasin_01',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'ruins_orbBasin_01TEST': {
+    'hash': 58180,
+    'name': 'ruins_orbBasin_01TEST',
+    'embedded': {
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {
+          'AddUnlockToPlayer': {
+            'hash': 1756836969,
+            'name': 'AddUnlockToPlayer'
+          },
+          'OrbBasinVfxController': {
+            'hash': 715394364,
+            'name': 'OrbBasinVfxController'
+          },
+          'PlayerUnlockStation': {
+            'hash': 2912807649,
+            'name': 'PlayerUnlockStation'
+          }
+        }
+      },
+      'ruins_orbBasin_01TEST_58178': {
+        'hash': 58178,
+        'name': 'ruins_orbBasin_01TEST',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'ruins_orbBasin_01_Variant': {
+    'hash': 13294,
+    'name': 'ruins_orbBasin_01_Variant',
+    'embedded': {
+      'Hand_Touch_46540': {
+        'hash': 46540,
+        'name': 'Hand_Touch',
+        'savables': {
+          'AddUnlockToPlayer': {
+            'hash': 1756836969,
+            'name': 'AddUnlockToPlayer'
+          },
+          'OrbBasinVfxController': {
+            'hash': 715394364,
+            'name': 'OrbBasinVfxController'
+          },
+          'PlayerUnlockStation': {
+            'hash': 2912807649,
+            'name': 'PlayerUnlockStation'
+          }
+        }
+      },
+      'ruins_orbBasin_01_Variant_24754': {
+        'hash': 24754,
+        'name': 'ruins_orbBasin_01_Variant',
+        'savables': {
+          'AdditionalStaticContent': {
+            'hash': 1908922854,
+            'name': 'AdditionalStaticContent'
+          }
+        }
+      }
+    }
+  },
+  'tallPot': {
+    'hash': 23320,
+    'name': 'tallPot',
+    'embedded': {}
+  },
+  'timberBlock_1Long': {
+    'hash': 34586,
+    'name': 'timberBlock_1Long',
+    'embedded': {
+      'timberBlock_1Long_46178': {
+        'hash': 46178,
+        'name': 'timberBlock_1Long',
+        'savables': {}
+      }
+    }
+  },
+  'timberBlock_2Long': {
+    'hash': 1898,
+    'name': 'timberBlock_2Long',
+    'embedded': {
+      'timberBlock_2Long_372': {
+        'hash': 372,
+        'name': 'timberBlock_2Long',
+        'savables': {}
+      }
+    }
+  },
+  'timberBlock_3Long': {
+    'hash': 1900,
+    'name': 'timberBlock_3Long',
+    'embedded': {
+      'timberBlock_3Long_376': {
+        'hash': 376,
+        'name': 'timberBlock_3Long',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_1x1': {
+    'hash': 50942,
+    'name': 'woodenPlatform_1x1',
+    'embedded': {
+      'woodenPlatform_1x1_4914': {
+        'hash': 4914,
+        'name': 'woodenPlatform_1x1',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_1x1_Torch': {
+    'hash': 64260,
+    'name': 'woodenPlatform_1x1_Torch',
+    'embedded': {
+      'Torch_Dock_15254': {
+        'hash': 15254,
+        'name': 'Torch_Dock',
+        'savables': {
+          'PickupDock': {
+            'hash': 2592242915,
+            'name': 'PickupDock'
+          }
+        }
+      },
+      'woodenPlatform_1x1_Torch_64256': {
+        'hash': 64256,
+        'name': 'woodenPlatform_1x1_Torch',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_1x2': {
+    'hash': 50950,
+    'name': 'woodenPlatform_1x2',
+    'embedded': {
+      'woodenPlatform_1x2_4598': {
+        'hash': 4598,
+        'name': 'woodenPlatform_1x2',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_Railings_1x1': {
+    'hash': 50946,
+    'name': 'woodenPlatform_Railings_1x1',
+    'embedded': {
+      'woodenPlatform_Railings_1x1_4200': {
+        'hash': 4200,
+        'name': 'woodenPlatform_Railings_1x1',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_Stairs_02': {
+    'hash': 50940,
+    'name': 'woodenPlatform_Stairs_02',
+    'embedded': {
+      'woodenPlatform_Stairs_02_3900': {
+        'hash': 3900,
+        'name': 'woodenPlatform_Stairs_02',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_T2x1': {
+    'hash': 50944,
+    'name': 'woodenPlatform_T2x1',
+    'embedded': {
+      'woodenPlatform_T2x1_3592': {
+        'hash': 3592,
+        'name': 'woodenPlatform_T2x1',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_T2x1_1': {
+    'hash': 50930,
+    'name': 'woodenPlatform_T2x1_1',
+    'embedded': {
+      'woodenPlatform_T2x1_1_3278': {
+        'hash': 3278,
+        'name': 'woodenPlatform_T2x1_1',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_W2x2': {
+    'hash': 50932,
+    'name': 'woodenPlatform_W2x2',
+    'embedded': {
+      'woodenPlatform_W2x2_2856': {
+        'hash': 2856,
+        'name': 'woodenPlatform_W2x2',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_W2x3': {
+    'hash': 10176,
+    'name': 'woodenPlatform_W2x3',
+    'embedded': {
+      'Breakable_Population_Area_32244': {
+        'hash': 32244,
+        'name': 'Breakable_Population_Area',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'woodenPlatform_W2x3_10188': {
+        'hash': 10188,
+        'name': 'woodenPlatform_W2x3',
+        'savables': {}
+      }
+    }
+  },
+  'woodenPlatform_W2x4': {
+    'hash': 33664,
+    'name': 'woodenPlatform_W2x4',
+    'embedded': {
+      'Breakable_Population_Area_35954': {
+        'hash': 35954,
+        'name': 'Breakable_Population_Area',
+        'savables': {
+          'PopulationSpawnArea': {
+            'hash': 3070493599,
+            'name': 'PopulationSpawnArea'
+          },
+          'SpawnArea': {
+            'hash': 2617495528,
+            'name': 'SpawnArea'
+          }
+        }
+      },
+      'woodenPlatform_W2x4_33680': {
+        'hash': 33680,
+        'name': 'woodenPlatform_W2x4',
+        'savables': {}
+      }
+    }
+  }
+} as const;
diff --git a/src/types/AngularVelocity.ts b/src/types/AngularVelocity.ts
new file mode 100644
index 0000000..44fbafe
--- /dev/null
+++ b/src/types/AngularVelocity.ts
@@ -0,0 +1,5 @@
+export type AngularVelocity = {
+  x: number;
+  y: number;
+  z: number;
+};
diff --git a/src/types/BinaryString.ts b/src/types/BinaryString.ts
new file mode 100644
index 0000000..68f591d
--- /dev/null
+++ b/src/types/BinaryString.ts
@@ -0,0 +1 @@
+export type BinaryString = string & { 'asserted with BinaryData.isBinaryString()': null };
diff --git a/src/ComponentHash.ts b/src/types/ComponentHash.ts
similarity index 91%
rename from src/ComponentHash.ts
rename to src/types/ComponentHash.ts
index 2900544..3d062ec 100644
--- a/src/ComponentHash.ts
+++ b/src/types/ComponentHash.ts
@@ -1,5 +1,7 @@
 export enum ComponentHash {
   // AdditionalOwnedDock = 2592242915, // Duplicate of PickupDock.
+  AdditionalStaticContent = 1908922854,
+  AreaOfInfluenceReceiver = 309083880,
   BasicDecay = 3801256786,
   BasicDynamicPath = 1624211074,
   BasicPopulationFolder = 1931537627,
@@ -22,6 +24,7 @@ export enum ComponentHash {
   Cookable = 205333986,
   CookingPot = 2882590463,
   Crank = 1588536425,
+  CurveOutput = 2576456808,
   CylindricalBoundsSurface = 34507654,
   DiggingImpactor = 3445325106,
   DirectionalBoundsSurface = 1962842866,
@@ -32,9 +35,11 @@ export enum ComponentHash {
   DurabilityModule = 1871432223,
   Ecosystem = 259381630,
   Embeddable = 22446553,
+  Enchantable = 4134534481,
   EnergyBasedHeatSource = 2721336102,
   Fire = 3457519710,
   // FireDissolve = 3457519710, // Duplicate of Fire.
+  FireLogic = 1509838052,
   FireStatusRaycastCrafter = 2718386020,
   ForestGenerator = 875684520,
   ForgedPointCollection = 2272630171,
@@ -70,6 +75,7 @@ export enum ComponentHash {
   LockableHinge = 1587058252,
   LogicBoolReceiver = 3751351177,
   LogicBoolSender = 1257282635,
+  LogicFloatChangeOnBool = 200292695,
   LogicFloatRangeReceiver = 2700376822,
   LogicFloatReceiver = 3188272159,
   LogicFloatReset = 3245685963,
@@ -80,14 +86,18 @@ export enum ComponentHash {
   LogicIntReceiver = 1081247904,
   LogicIntSender = 2880587164,
   LogicIntThresholdReceiver = 2563434699,
+  LogicReset = 1934129787,
   LogicSumFloatReceiver = 2814234626,
   LogicSumIntReceiver = 1964978567,
   'LogicValueSender`1' = 3810525047,
   LogicVector3Receiver = 1228539097,
   LogicVector3Sender = 2026743731,
+  LogicIntToBool = 2253011220,
   LootModule = 634164392,
+  MRK_ActivationLever = 2069630919,
   MapBoard = 2443660852,
   MeshPlacement = 2169673426,
+  ModifiableAdditionalStaticContent = 159391088,
   ModifiableStaticManager = 3674519521,
   Mould = 391977879,
   MouldRestrictor = 1571096900,
@@ -97,6 +107,7 @@ export enum ComponentHash {
   NetworkedFloatStream = 2127962967,
   NetworkRigidbody = 2290978823,
   OfflinePlayerProgressionHandler = 2293737711,
+  OneTimeUpgradeuinteraction = 3230087383,
   PageInstance = 1923918202,
   PaperPageInstance = 2241532968,
   PhysicalMaterialPart = 272188517,
@@ -106,11 +117,13 @@ export enum ComponentHash {
   PlaceItemNoDockFirePuzzleLogic = 2495475500,
   PlaceItemNoDockPuzzleLogic = 1176706580,
   PlaceItemPuzzleLogic = 1001395212,
+  PlayerDetect = 403040752,
   PlayerInteractionManager = 1211178616,
   PlayerInteractionRestrictor = 2951515968,
   PlayerLandmark = 1946741389,
   PlayerProxy = 1233775263,
   PlayerStatManager = 2743469720,
+  PlayerUnlockStation = 2912807649,
   PopulationDefinitionManager = 2978388169,
   PopulationFolder = 1431397437,
   'PopulationFolder`2' = 986260983,
@@ -122,6 +135,7 @@ export enum ComponentHash {
   RaycastCrafter = 2815374842,
   Recycler = 2450553269,
   RepairBox = 3820454400,
+  RespawnOnDestroy = 830106687,
   RockCluster = 1651678475,
   RopeGrab = 237360636,
   RotatePickup = 2498617949,
diff --git a/src/types/EntityKey.ts b/src/types/EntityKey.ts
new file mode 100644
index 0000000..c544f47
--- /dev/null
+++ b/src/types/EntityKey.ts
@@ -0,0 +1,7 @@
+import type { ATTPrefabName } from './ATTPrefabName.js';
+
+import { ATTPrefabs } from './ATTPrefabs.js';
+
+export type EntityKey<TPrefabName extends ATTPrefabName> =
+  | keyof (typeof ATTPrefabs)[TPrefabName]['embedded']
+  | 'Unknown';
diff --git a/src/types/LogicOperator.ts b/src/types/LogicOperator.ts
new file mode 100644
index 0000000..38da85e
--- /dev/null
+++ b/src/types/LogicOperator.ts
@@ -0,0 +1,7 @@
+export enum LogicOperator {
+  And = 0,
+  Or = 1,
+  Xor = 2,
+  Nand = 3,
+  Toggle = 4
+}
diff --git a/src/PhysicalMaterialPartHash.ts b/src/types/PhysicalMaterialPartHash.ts
similarity index 96%
rename from src/PhysicalMaterialPartHash.ts
rename to src/types/PhysicalMaterialPartHash.ts
index 9712c1f..57b786d 100644
--- a/src/PhysicalMaterialPartHash.ts
+++ b/src/types/PhysicalMaterialPartHash.ts
@@ -8,6 +8,7 @@ export enum PhysicalMaterialPartHash {
   Copper = 20186,
   DaisLeather = 33384,
   DaisRedLeather = 37850,
+  DarkSteelAlloy = 55232,
   EvinonSteelAlloy = 31502,
   Gold = 56394,
   Iron = 1,
diff --git a/src/PopulationDefinitionHash.ts b/src/types/PopulationDefinitionHash.ts
similarity index 100%
rename from src/PopulationDefinitionHash.ts
rename to src/types/PopulationDefinitionHash.ts
diff --git a/src/types/PopulationDefinitionName.ts b/src/types/PopulationDefinitionName.ts
new file mode 100644
index 0000000..ddf3622
--- /dev/null
+++ b/src/types/PopulationDefinitionName.ts
@@ -0,0 +1,3 @@
+import type { PopulationDefinitionHash } from './PopulationDefinitionHash.js';
+
+export type PopulationDefinitionName = keyof typeof PopulationDefinitionHash;
diff --git a/src/types/Position.ts b/src/types/Position.ts
new file mode 100644
index 0000000..a6b48c5
--- /dev/null
+++ b/src/types/Position.ts
@@ -0,0 +1,5 @@
+export type Position = {
+  x: number;
+  y: number;
+  z: number;
+};
diff --git a/src/types/PrefabChild.ts b/src/types/PrefabChild.ts
new file mode 100644
index 0000000..67faf40
--- /dev/null
+++ b/src/types/PrefabChild.ts
@@ -0,0 +1,6 @@
+import type { Prefab } from '../Prefab.js';
+
+export type PrefabChild = {
+  parentHash: number;
+  prefab: Prefab;
+};
diff --git a/src/types/PrefabComponents.ts b/src/types/PrefabComponents.ts
new file mode 100644
index 0000000..0247697
--- /dev/null
+++ b/src/types/PrefabComponents.ts
@@ -0,0 +1,5 @@
+import type { SupportedPrefabComponents } from './SupportedPrefabComponents.js';
+import type { UnknownPrefabComponents } from './UnknownPrefabComponents.js';
+import type { UnsupportedPrefabComponents } from './UnsupportedPrefabComponents.js';
+
+export type PrefabComponents = SupportedPrefabComponents & UnsupportedPrefabComponents & UnknownPrefabComponents;
diff --git a/src/types/PrefabEntities.ts b/src/types/PrefabEntities.ts
new file mode 100644
index 0000000..1da36c9
--- /dev/null
+++ b/src/types/PrefabEntities.ts
@@ -0,0 +1,7 @@
+import type { ATTPrefabName } from './ATTPrefabName.js';
+import type { EntityKey } from './EntityKey.js';
+import type { Entity } from '../Entity.js';
+
+export type PrefabEntities<TPrefabName extends ATTPrefabName> = {
+  [Key in EntityKey<TPrefabName>]?: Entity<TPrefabName>;
+};
diff --git a/src/PresetHash.ts b/src/types/PresetHash.ts
similarity index 100%
rename from src/PresetHash.ts
rename to src/types/PresetHash.ts
diff --git a/src/types/Rotation.ts b/src/types/Rotation.ts
new file mode 100644
index 0000000..37d45cb
--- /dev/null
+++ b/src/types/Rotation.ts
@@ -0,0 +1,6 @@
+export type Rotation = {
+  x: number;
+  y: number;
+  z: number;
+  w: number;
+};
diff --git a/src/types/SaveString.ts b/src/types/SaveString.ts
new file mode 100644
index 0000000..201b12e
--- /dev/null
+++ b/src/types/SaveString.ts
@@ -0,0 +1 @@
+export type SaveString = string & { 'asserted with BinaryData.isSaveString()': null };
diff --git a/src/types/SetSpawnAreaProps.ts b/src/types/SetSpawnAreaProps.ts
new file mode 100644
index 0000000..e095dc2
--- /dev/null
+++ b/src/types/SetSpawnAreaProps.ts
@@ -0,0 +1,13 @@
+import type { PopulationSpawnAreaComponentProps } from '../components/PopulationSpawnAreaComponent.js';
+import type { SpawnAreaComponentProps } from '../components/SpawnAreaComponent.js';
+
+export type SetSpawnAreaProps = Pick<
+  PopulationSpawnAreaComponentProps,
+  | 'currentPopulation'
+  | 'isOneOff'
+  | 'isPopulationStarted'
+  | 'maxPopulation'
+  | 'numberOfSpawnPoints'
+  | 'startingPopulation'
+> &
+  Pick<SpawnAreaComponentProps, 'size'>;
diff --git a/src/types/SpeciesHash.ts b/src/types/SpeciesHash.ts
new file mode 100644
index 0000000..c65a314
--- /dev/null
+++ b/src/types/SpeciesHash.ts
@@ -0,0 +1,8 @@
+export enum SpeciesHash {
+  Ash = 31500,
+  Birch = 4442,
+  Oak = 11232,
+  Standard = 56530,
+  Redwood = 7386,
+  Walnut = 28044
+}
diff --git a/src/types/SupportedComponent.ts b/src/types/SupportedComponent.ts
new file mode 100644
index 0000000..af186da
--- /dev/null
+++ b/src/types/SupportedComponent.ts
@@ -0,0 +1,55 @@
+import type { LogicIntSenderComponent } from '../components/LogicIntSenderComponent.js';
+
+import { BasicDecayComponent } from '../components/BasicDecayComponent.js';
+import { DoorComponent } from '../components/DoorComponent.js';
+import { DurabilityModuleComponent } from '../components/DurabilityModuleComponent.js';
+import { FireComponent } from '../components/FireComponent.js';
+import { FuseComponent } from '../components/FuseComponent.js';
+import { HeatSourceBaseComponent } from '../components/HeatSourceBaseComponent.js';
+import { LiquidContainerComponent } from '../components/LiquidContainerComponent.js';
+import { LogicBoolReceiverComponent } from '../components/LogicBoolReceiverComponent.js';
+import { LogicBoolSenderComponent } from '../components/LogicBoolSenderComponent.js';
+import { LogicFloatReceiverComponent } from '../components/LogicFloatReceiverComponent.js';
+import { LogicFloatSenderComponent } from '../components/LogicFloatSenderComponent.js';
+import { LogicGateReceiverComponent } from '../components/LogicGateReceiverComponent.js';
+import { LogicIntReceiverComponent } from '../components/LogicIntReceiverComponent.js';
+import { LogicVector3ReceiverComponent } from '../components/LogicVector3ReceiverComponent.js';
+import { LogicVector3SenderComponent } from '../components/LogicVector3SenderComponent.js';
+import { NetworkRigidbodyComponent } from '../components/NetworkRigidbodyComponent.js';
+import { PhysicalMaterialPartComponent } from '../components/PhysicalMaterialPartComponent.js';
+import { PickupComponent } from '../components/PickupComponent.js';
+import { PickupDockComponent } from '../components/PickupDockComponent.js';
+import { PopulationSpawnAreaComponent } from '../components/PopulationSpawnAreaComponent.js';
+import { SentGiftComponent } from '../components/SentGiftComponent.js';
+import { SlidingDoorComponent } from '../components/SlidingDoorComponent.js';
+import { SpawnAreaComponent } from '../components/SpawnAreaComponent.js';
+import { StatManagerComponent } from '../components/StatManagerComponent.js';
+import { WoodcutTreeComponent } from '../components/WoodcutTreeComponent.js';
+
+export type SupportedComponent =
+  | typeof BasicDecayComponent
+  | typeof DoorComponent
+  | typeof DurabilityModuleComponent
+  | typeof FireComponent
+  | typeof FuseComponent
+  | typeof HeatSourceBaseComponent
+  | typeof LiquidContainerComponent
+  | typeof LogicBoolReceiverComponent
+  | typeof LogicBoolSenderComponent
+  | typeof LogicFloatReceiverComponent
+  | typeof LogicFloatSenderComponent
+  | typeof LogicGateReceiverComponent
+  | typeof LogicIntReceiverComponent
+  | typeof LogicIntSenderComponent
+  | typeof LogicVector3ReceiverComponent
+  | typeof LogicVector3SenderComponent
+  | typeof NetworkRigidbodyComponent
+  | typeof PhysicalMaterialPartComponent
+  | typeof PickupComponent
+  | typeof PickupDockComponent
+  | typeof PopulationSpawnAreaComponent
+  | typeof SentGiftComponent
+  | typeof SlidingDoorComponent
+  | typeof SpawnAreaComponent
+  | typeof StatManagerComponent
+  | typeof WoodcutTreeComponent;
diff --git a/src/types/SupportedPrefabComponents.ts b/src/types/SupportedPrefabComponents.ts
new file mode 100644
index 0000000..c0be69a
--- /dev/null
+++ b/src/types/SupportedPrefabComponents.ts
@@ -0,0 +1,55 @@
+import type { BasicDecayComponent } from '../components/BasicDecayComponent.js';
+import type { DoorComponent } from '../components/DoorComponent.js';
+import type { DurabilityModuleComponent } from '../components/DurabilityModuleComponent.js';
+import type { FireComponent } from '../components/FireComponent.js';
+import type { FuseComponent } from '../components/FuseComponent.js';
+import type { HeatSourceBaseComponent } from '../components/HeatSourceBaseComponent.js';
+import type { LiquidContainerComponent } from '../components/LiquidContainerComponent.js';
+import type { LogicBoolReceiverComponent } from '../components/LogicBoolReceiverComponent.js';
+import type { LogicBoolSenderComponent } from '../components/LogicBoolSenderComponent.js';
+import type { LogicFloatReceiverComponent } from '../components/LogicFloatReceiverComponent.js';
+import type { LogicFloatSenderComponent } from '../components/LogicFloatSenderComponent.js';
+import type { LogicGateReceiverComponent } from '../components/LogicGateReceiverComponent.js';
+import type { LogicIntReceiverComponent } from '../components/LogicIntReceiverComponent.js';
+import type { LogicIntSenderComponent } from '../components/LogicIntSenderComponent.js';
+import type { LogicVector3ReceiverComponent } from '../components/LogicVector3ReceiverComponent.js';
+import type { LogicVector3SenderComponent } from '../components/LogicVector3SenderComponent.js';
+import type { NetworkRigidbodyComponent } from '../components/NetworkRigidbodyComponent.js';
+import type { PhysicalMaterialPartComponent } from '../components/PhysicalMaterialPartComponent.js';
+import type { PickupComponent } from '../components/PickupComponent.js';
+import type { PickupDockComponent } from '../components/PickupDockComponent.js';
+import type { PopulationSpawnAreaComponent } from '../components/PopulationSpawnAreaComponent.js';
+import type { SentGiftComponent } from '../components/SentGiftComponent.js';
+import type { SlidingDoorComponent } from '../components/SlidingDoorComponent.js';
+import type { SpawnAreaComponent } from '../components/SpawnAreaComponent.js';
+import type { StatManagerComponent } from '../components/StatManagerComponent.js';
+import type { WoodcutTreeComponent } from '../components/WoodcutTreeComponent.js';
+
+export type SupportedPrefabComponents = {
+  BasicDecay?: BasicDecayComponent;
+  Door?: DoorComponent;
+  DurabilityModule?: DurabilityModuleComponent;
+  Fire?: FireComponent;
+  Fuse?: FuseComponent;
+  HeatSourceBase?: HeatSourceBaseComponent;
+  LiquidContainer?: LiquidContainerComponent;
+  LogicBoolReceiver?: LogicBoolReceiverComponent;
+  LogicBoolSender?: LogicBoolSenderComponent;
+  LogicFloatReceiver?: LogicFloatReceiverComponent;
+  LogicFloatSender?: LogicFloatSenderComponent;
+  LogicGateReceiver?: LogicGateReceiverComponent;
+  LogicIntReceiver?: LogicIntReceiverComponent;
+  LogicIntSender?: LogicIntSenderComponent;
+  LogicVector3Receiver?: LogicVector3ReceiverComponent;
+  LogicVector3Sender?: LogicVector3SenderComponent;
+  NetworkRigidbody?: NetworkRigidbodyComponent;
+  PhysicalMaterialPart?: PhysicalMaterialPartComponent;
+  Pickup?: PickupComponent;
+  PickupDock?: PickupDockComponent;
+  PopulationSpawnArea?: PopulationSpawnAreaComponent;
+  SentGift?: SentGiftComponent;
+  SlidingDoor?: SlidingDoorComponent;
+  SpawnArea?: SpawnAreaComponent;
+  StatManager?: StatManagerComponent;
+  WoodcutTree?: WoodcutTreeComponent;
+};
diff --git a/src/types/UnknownPrefabComponents.ts b/src/types/UnknownPrefabComponents.ts
new file mode 100644
index 0000000..0ff80cc
--- /dev/null
+++ b/src/types/UnknownPrefabComponents.ts
@@ -0,0 +1,3 @@
+import type { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+
+export type UnknownPrefabComponents = { Unknown: UnsupportedComponent[] };
diff --git a/src/types/UnsupportedPrefabComponents.ts b/src/types/UnsupportedPrefabComponents.ts
new file mode 100644
index 0000000..5c1bd24
--- /dev/null
+++ b/src/types/UnsupportedPrefabComponents.ts
@@ -0,0 +1,9 @@
+import type { ComponentHash } from './ComponentHash.js';
+import type { SupportedPrefabComponents } from './SupportedPrefabComponents.js';
+import type { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+
+type ComponentName = keyof typeof ComponentHash;
+
+type UnsupportedComponentName = Exclude<ComponentName, keyof SupportedPrefabComponents>;
+
+export type UnsupportedPrefabComponents = { [K in UnsupportedComponentName]?: UnsupportedComponent };
diff --git a/src/types/Velocity.ts b/src/types/Velocity.ts
new file mode 100644
index 0000000..f427b1f
--- /dev/null
+++ b/src/types/Velocity.ts
@@ -0,0 +1,5 @@
+export type Velocity = {
+  x: number;
+  y: number;
+  z: number;
+};
diff --git a/src/utils/binaryToInt.ts b/src/utils/binaryToInt.ts
deleted file mode 100644
index c559f02..0000000
--- a/src/utils/binaryToInt.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export const binaryToInt = (binary: string): number => {
-  const isPositive = Boolean(Number(binary.slice(0, 1)));
-  const integer = Number(`0b0${binary.slice(1)}`);
-
-  return isPositive ? integer : integer - 2147483648;
-};
diff --git a/src/utils/binaryToNumber.ts b/src/utils/binaryToNumber.ts
deleted file mode 100644
index 3f79a12..0000000
--- a/src/utils/binaryToNumber.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const binaryToNumber = (binary: string): number => Number(`0b${binary}`);
diff --git a/src/utils/binaryToUIntArray.ts b/src/utils/binaryToUIntArray.ts
deleted file mode 100644
index 09e96fd..0000000
--- a/src/utils/binaryToUIntArray.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { binaryToNumber } from './binaryToNumber';
-
-export const binaryToUIntArray = (binary: string): number[] => {
-  if (binary.length % 32 !== 0) throw Error('Cannot convert binary to UInts. Bit count is not divisible by 32.');
-
-  return binary.match(/.{32}/g)?.map(bits => binaryToNumber(bits)) ?? [];
-};
diff --git a/src/utils/binaryToULong.ts b/src/utils/binaryToULong.ts
deleted file mode 100644
index 2619031..0000000
--- a/src/utils/binaryToULong.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const binaryToULong = (binary: string): number => Number(`0b${binary.slice(32)}${binary.slice(0, 32)}`);
diff --git a/src/utils/composeTree.ts b/src/utils/composeTree.ts
deleted file mode 100644
index 59ee565..0000000
--- a/src/utils/composeTree.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-import { ChildPrefab } from '../decoders';
-import { PrefabHash } from '../PrefabHash';
-import { PrefabEmbeddedEntityHash } from '../PrefabEmbeddedEntityHash';
-
-type Tree = {
-  [segment in keyof typeof PrefabEmbeddedEntityHash]?: EmbeddedEntities | null;
-};
-
-type EmbeddedEntities = {
-  [embeddedEntity: string]: Tree;
-};
-
-type CompositionMap = {
-  [prefab: string]: {
-    [embeddedEntity: string]: string[];
-  };
-};
-
-const ROOTS = [
-  'Woodcut_Root_V1_T0',
-  'Woodcut_Root_V1_T0_B15',
-  'Woodcut_Root_V1_T0_S30',
-  'Woodcut_Root_V1_T30',
-  'Woodcut_BranchRoot_V1_B0',
-  'Woodcut_BranchRoot_V1_B15_S30'
-];
-
-const TRUNKS = [
-  'Woodcut_T0_B0_B30',
-  'Woodcut_T0_B15_B30',
-  'Woodcut_T0_T0',
-  'Woodcut_T0_T0_B30',
-  'Woodcut_T0_T0_B45',
-  'Woodcut_T0_T0_S30',
-  'Woodcut_T0_T0_S30_S30_S30',
-  'Woodcut_T15_T15',
-  'Woodcut_T30_T30',
-  'Woodcut_T5_T5'
-];
-
-const BRANCHES = [
-  'Woodcut_B0_B0',
-  'Woodcut_B0_B0_S15',
-  'Woodcut_B0_B15_B30',
-  'Woodcut_B0_S0_S30',
-  'Woodcut_B15_B15',
-  'Woodcut_B30_B30',
-  'Woodcut_B5_B5'
-];
-
-const STICKS = ['Woodcut_S0_S0', 'Woodcut_S0_S15_S15'];
-
-const LEAVES = [
-  'Woodcut_Leaves_V1_L_F',
-  'Woodcut_Leaves_V1_L_S',
-  'Woodcut_Leaves_V1_S_F',
-  'Woodcut_Leaves_V1_S_S'
-  // 'Woodcut_Leaves_V2_D',
-  // 'Woodcut_Leaves_V2_L',
-  // 'Woodcut_Leaves_V2_Topper'
-];
-
-const compositionMap: CompositionMap = {
-  Woodcut_B0_B0: { Top: BRANCHES },
-  Woodcut_B0_B0_S15: { Top: BRANCHES, Stick: STICKS },
-  Woodcut_B0_B15_B30: { Branch_1: BRANCHES, Branch_2: BRANCHES },
-  Woodcut_B0_S0_S30: { Stick_1: STICKS, Stick_2: STICKS },
-  Woodcut_B15_B15: { Top: BRANCHES },
-  Woodcut_B30_B30: { Top: BRANCHES },
-  Woodcut_B5_B5: { Top: BRANCHES },
-  Woodcut_BranchRoot_V1_B0: { Top: BRANCHES },
-  Woodcut_BranchRoot_V1_B15_S30: { Top: BRANCHES, Branch: STICKS },
-  Woodcut_Root_V1_T0: { Top: TRUNKS },
-  Woodcut_Root_V1_T0_B15: { Top: TRUNKS, Branch: BRANCHES },
-  Woodcut_Root_V1_T0_S30: { Top: TRUNKS, Stick: STICKS },
-  Woodcut_Root_V1_T30: { Top: TRUNKS },
-  Woodcut_S0_S0: { Top: STICKS },
-  Woodcut_S0_S15_S15: { Top_1: STICKS, Top_2: STICKS },
-  Woodcut_T0_B0_B30: { Branch_1: BRANCHES, Branch_2: BRANCHES },
-  Woodcut_T0_B15_B30: { Branch_1: BRANCHES, Branch_2: BRANCHES },
-  Woodcut_T0_T0: { Top: TRUNKS },
-  Woodcut_T0_T0_B30: { Top: TRUNKS, Branch: BRANCHES },
-  Woodcut_T0_T0_B45: { Top: TRUNKS, Branch: BRANCHES },
-  Woodcut_T0_T0_S30: { Top: TRUNKS, Stick: STICKS },
-  Woodcut_T0_T0_S30_S30_S30: { Top: TRUNKS, Stick_1: STICKS, Stick_2: STICKS, Stick_3: STICKS },
-  Woodcut_T15_T15: { Top: TRUNKS },
-  Woodcut_T30_T30: { Top: TRUNKS },
-  Woodcut_T5_T5: { Top: TRUNKS }
-};
-
-const pickRandom = <T>(choices: T[]) => {
-  const index = Math.floor(Math.random() * choices.length);
-
-  return choices[index];
-};
-
-export const generateComposition = (terminationRate: number) => {
-  const terminationThreshold = 0;
-  const root = pickRandom(ROOTS);
-
-  const composition: Tree = generateLayer(root, terminationRate, terminationThreshold);
-
-  return composition;
-};
-
-const generateLayer = (
-  baseSegment: string,
-  terminationRate: number,
-  terminationThreshold: number,
-  isTerminationLayer: boolean = false
-): Tree => {
-  const baseSegmentConnections = Object.keys(compositionMap[baseSegment] ?? {});
-  const layerConnection = baseSegmentConnections.length ? {} : null;
-
-  /* Prepare layer. */
-  const layer: Tree = {
-    [baseSegment]: layerConnection
-  };
-
-  if (isTerminationLayer) {
-    /* Terminate all connections with random leaf nodes. */
-    for (const connection of baseSegmentConnections) {
-      const segment = pickRandom(LEAVES);
-      const subtree: Tree = { [segment]: null };
-
-      layer[baseSegment]![connection] = subtree;
-    }
-  } else {
-    /* Increase termination chance and generate the next layer. */
-    const newTerminationThreshold = Math.min(1, terminationThreshold + terminationRate);
-    const terminateNextLayer = Math.random() <= newTerminationThreshold;
-
-    /* Append all connection with random matching segments. */
-    for (const connection of baseSegmentConnections) {
-      const segmentCandidates = compositionMap[baseSegment][connection];
-      const segment = pickRandom(segmentCandidates);
-      const subtree: Tree = generateLayer(segment, terminationRate, newTerminationThreshold, terminateNextLayer);
-
-      layer[baseSegment]![connection] = subtree;
-    }
-  }
-
-  return layer;
-};
-
-export const composeTree = (tree: Tree, parentHash: number = 0): ChildPrefab => {
-  const [segment, embeddedEntities] = Object.entries(tree)[0];
-
-  return {
-    parentHash,
-    prefab: {
-      prefabObject: {
-        hash: PrefabHash[segment as keyof typeof PrefabHash]
-      },
-      childPrefabs:
-        embeddedEntities === null
-          ? []
-          : Object.entries(embeddedEntities!).map(([embeddedEntity, subtree]) =>
-              composeTree(subtree, PrefabEmbeddedEntityHash[segment][embeddedEntity])
-            )
-    }
-  };
-};
diff --git a/src/utils/createBinaryReader.ts b/src/utils/createBinaryReader.ts
deleted file mode 100644
index 0179f9a..0000000
--- a/src/utils/createBinaryReader.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { binaryToNumber } from './binaryToNumber';
-import { binaryToInt } from './binaryToInt';
-import { binaryToULong } from './binaryToULong';
-import { unpackFloat } from './unpackFloat';
-
-type Index = { current: number };
-
-export type BinaryReader = {
-  binary: (bits: number) => string;
-  boolean: () => boolean;
-  uInt: () => number;
-  uLong: () => number;
-  float: () => number;
-  int: () => number;
-};
-
-export const createBinaryReader = (binary: string): BinaryReader => {
-  const index: Index = { current: 0 };
-  const size = binary.length;
-
-  return {
-    binary: function (bits: number): string {
-      if (index.current + bits > size) {
-        throw Error(`Cannot read ${bits} bits from binary at index ${index.current}. Binary is only ${size} bits.`);
-      }
-
-      return binary.slice(index.current, (index.current += bits));
-    },
-
-    boolean: function () {
-      const bit = this.binary(1);
-
-      return Boolean(Number(bit));
-    },
-
-    uInt: function () {
-      const bits = this.binary(32);
-
-      return binaryToNumber(bits);
-    },
-
-    uLong: function () {
-      const bits = this.binary(64);
-
-      return binaryToULong(bits);
-    },
-
-    float: function () {
-      const uInt = this.uInt();
-
-      return unpackFloat(uInt);
-    },
-
-    int: function () {
-      const bits = this.binary(32);
-
-      return binaryToInt(bits);
-    }
-  };
-};
diff --git a/src/utils/createBinaryWriter.ts b/src/utils/createBinaryWriter.ts
deleted file mode 100644
index 0a2ad76..0000000
--- a/src/utils/createBinaryWriter.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { floatToBinary } from './floatToBinary';
-import { uLongToBinary } from './uLongToBinary';
-import { intToBinary } from './intToBinary';
-import { uIntToBinary } from './uIntToBinary';
-
-export type BinaryWriter = {
-  binary: (bits: string) => void;
-  boolean: (bit: boolean) => void;
-  uInt: (number: number) => void;
-  uLong: (number: number) => void;
-  float: (number: number) => void;
-  int: (number: number) => void;
-  flush: () => string;
-};
-
-export const createBinaryWriter = (): BinaryWriter => {
-  let binary: string = '';
-
-  return {
-    binary: function (bits: string): void {
-      binary += bits;
-    },
-
-    boolean: function (bit: boolean) {
-      binary += Number(bit).toString();
-    },
-
-    uInt: function (number: number) {
-      binary += uIntToBinary(number);
-    },
-
-    uLong: function (number: number) {
-      binary += uLongToBinary(number);
-    },
-
-    float: function (number: number) {
-      binary += floatToBinary(number);
-    },
-
-    int: function (number: number) {
-      binary += intToBinary(number);
-    },
-
-    flush: function () {
-      const result = binary;
-      binary = '';
-
-      return result;
-    }
-  };
-};
diff --git a/src/utils/floatToBinary.ts b/src/utils/floatToBinary.ts
deleted file mode 100644
index b82deaf..0000000
--- a/src/utils/floatToBinary.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { packFloat } from './packFloat';
-import { numberToBinary } from './numberToBinary';
-
-export const floatToBinary = (number: number): string => numberToBinary(packFloat(number)).padStart(32, '0');
diff --git a/src/utils/index.ts b/src/utils/index.ts
deleted file mode 100644
index 9b00556..0000000
--- a/src/utils/index.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export { binaryToNumber } from './binaryToNumber';
-export { binaryToInt } from './binaryToInt';
-export { binaryToUIntArray } from './binaryToUIntArray';
-export { binaryToULong } from './binaryToULong';
-export { composeTree, generateComposition } from './composeTree';
-export { createBinaryReader, BinaryReader } from './createBinaryReader';
-export { createBinaryWriter, BinaryWriter } from './createBinaryWriter';
-export { floatToBinary } from './floatToBinary';
-export { intToBinary } from './intToBinary';
-export { numberToBinary } from './numberToBinary';
-export { uIntToBinary } from './uIntToBinary';
-export { uLongToBinary } from './uLongToBinary';
-export { unpackFloat } from './unpackFloat';
diff --git a/src/utils/intToBinary.ts b/src/utils/intToBinary.ts
deleted file mode 100644
index c4fb1d9..0000000
--- a/src/utils/intToBinary.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { numberToBinary } from './numberToBinary';
-
-const NEGATIVE_OFFSET = 2147483648;
-
-export const intToBinary = (number: number): string => {
-  const isPositive = number >= 0;
-  const integer = isPositive ? number : number + NEGATIVE_OFFSET;
-
-  const isPositiveBit = Number(isPositive).toString();
-  const integerBits = numberToBinary(integer).padStart(32, '0');
-
-  return `${isPositiveBit}${integerBits.slice(1)}`;
-};
diff --git a/src/utils/isATTPrefabHash.test.ts b/src/utils/isATTPrefabHash.test.ts
new file mode 100644
index 0000000..d213dcb
--- /dev/null
+++ b/src/utils/isATTPrefabHash.test.ts
@@ -0,0 +1,25 @@
+import { ATTPrefabs } from '../types/ATTPrefabs.js';
+
+import { isATTPrefabHash } from './isATTPrefabHash.js';
+
+describe('isATTPrefabHash()', () => {
+  describe('when given a valid prefab hash', () => {
+    it('returns true', () => {
+      const validHash = ATTPrefabs.Handle_Short.hash;
+
+      const result = isATTPrefabHash(validHash);
+
+      expect(result).toBe(true);
+    });
+  });
+
+  describe('when given an invalid prefab hash', () => {
+    it('returns false', () => {
+      const invalidHash = 0;
+
+      const result = isATTPrefabHash(invalidHash);
+
+      expect(result).toBe(false);
+    });
+  });
+});
diff --git a/src/utils/isATTPrefabHash.ts b/src/utils/isATTPrefabHash.ts
new file mode 100644
index 0000000..9be5775
--- /dev/null
+++ b/src/utils/isATTPrefabHash.ts
@@ -0,0 +1,20 @@
+import type { ATTPrefabHash } from '../types/ATTPrefabHash.js';
+
+import { attPrefabHashes } from '../constants.js';
+
+/**
+ * Asserts if a `number` is an [`ATTPrefabHash`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/ATTPrefabHash.md).
+ *
+ * @example
+ * import { isATTPrefabHash } from 'att-string-transcoder';
+ *
+ * const prefabHash = 23182;
+ * // `prefabHash` is of type `number`.
+ *
+ * if (isATTPrefabHash(prefabHash)) {
+ *   // `prefabHash` is of type `ATTPrefabHash`.
+ * }
+ */
+export function isATTPrefabHash(hash: number): hash is ATTPrefabHash {
+  return attPrefabHashes.includes(hash);
+}
diff --git a/src/utils/isATTPrefabName.test.ts b/src/utils/isATTPrefabName.test.ts
new file mode 100644
index 0000000..dccf4ae
--- /dev/null
+++ b/src/utils/isATTPrefabName.test.ts
@@ -0,0 +1,25 @@
+import { ATTPrefabs } from '../types/ATTPrefabs.js';
+
+import { isATTPrefabName } from './isATTPrefabName.js';
+
+describe('isATTPrefabName()', () => {
+  describe('when given a valid prefab name', () => {
+    it('returns true', () => {
+      const validName = ATTPrefabs.Handle_Short.name;
+
+      const result = isATTPrefabName(validName);
+
+      expect(result).toBe(true);
+    });
+  });
+
+  describe('when given an invalid prefab name', () => {
+    it('returns false', () => {
+      const invalidName = 'topkek';
+
+      const result = isATTPrefabName(invalidName);
+
+      expect(result).toBe(false);
+    });
+  });
+});
diff --git a/src/utils/isATTPrefabName.ts b/src/utils/isATTPrefabName.ts
new file mode 100644
index 0000000..0a8f9b6
--- /dev/null
+++ b/src/utils/isATTPrefabName.ts
@@ -0,0 +1,20 @@
+import type { ATTPrefabName } from '../types/ATTPrefabName.js';
+
+import { ATTPrefabs } from '../types/ATTPrefabs.js';
+
+/**
+ * Asserts if a `string` is an [`ATTPrefabName`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/ATTPrefabName.md).
+ *
+ * @example
+ * import { isATTPrefabName } from 'att-string-transcoder';
+ *
+ * const prefabName = 'Anvil';
+ * // `prefabName` is of type `string`.
+ *
+ * if (isATTPrefabName(prefabName)) {
+ *   // `prefabName` is of type `ATTPrefabName`.
+ * }
+ */
+export function isATTPrefabName(name: string): name is ATTPrefabName {
+  return name in ATTPrefabs;
+}
diff --git a/src/utils/isSavableComponent.test.ts b/src/utils/isSavableComponent.test.ts
new file mode 100644
index 0000000..dff7a4b
--- /dev/null
+++ b/src/utils/isSavableComponent.test.ts
@@ -0,0 +1,38 @@
+import { ATTPrefabs } from '../types/ATTPrefabs.js';
+
+import { isSavableComponent } from './isSavableComponent.js';
+
+describe('isSavableComponent()', () => {
+  describe('when given a valid component name on a corresponding prefab hash', () => {
+    it('returns true', () => {
+      const validComponentName = ATTPrefabs.Potion_Medium.embedded.Potion_Medium_23646.savables.Pickup.name;
+      const correspondingPrefabHash = ATTPrefabs.Potion_Medium.hash;
+
+      const result = isSavableComponent(validComponentName, correspondingPrefabHash);
+
+      expect(result).toBe(true);
+    });
+  });
+
+  describe('when given a valid component name on a corresponding prefab name', () => {
+    it('returns true', () => {
+      const validComponentName = ATTPrefabs.Potion_Medium.embedded.Potion_Medium_23646.savables.Pickup.name;
+      const correspondingPrefabName = ATTPrefabs.Potion_Medium.name;
+
+      const result = isSavableComponent(validComponentName, correspondingPrefabName);
+
+      expect(result).toBe(true);
+    });
+  });
+
+  describe('when given a valid component name on a prefab name that does not correspond to the component', () => {
+    it('returns false', () => {
+      const validComponentName = ATTPrefabs.Potion_Medium.embedded.Potion_Medium_23646.savables.Pickup.name;
+      const nonCorrespondingPrefabName = ATTPrefabs.Anvil.name;
+
+      const result = isSavableComponent(validComponentName, nonCorrespondingPrefabName);
+
+      expect(result).toBe(false);
+    });
+  });
+});
diff --git a/src/utils/isSavableComponent.ts b/src/utils/isSavableComponent.ts
new file mode 100644
index 0000000..344d301
--- /dev/null
+++ b/src/utils/isSavableComponent.ts
@@ -0,0 +1,32 @@
+import type { ATTPrefabHash } from '../types/ATTPrefabHash.js';
+import type { ATTPrefabName } from '../types/ATTPrefabName.js';
+import type { SupportedPrefabComponents } from '../types/SupportedPrefabComponents.js';
+
+import { attPrefabNames } from '../constants.js';
+import { ATTPrefabs } from '../types/ATTPrefabs.js';
+
+type Embed = { savables?: { [saveable: string]: { hash: number; name: string } } };
+
+/**
+ * Returns whether or not the given component name belongs to a component that is normally savable
+ * on the given prefab hash or name.
+ *
+ * @example
+ * import { isSavableComponent } from 'att-string-transcoder';
+ *
+ * if (isSavableComponent('NetworkRigidbody', 'Handle_Short')) {
+ *   // `Handle_Short` can save `NetworkRigidbody` component data.
+ * }
+ */
+export function isSavableComponent(componentName: keyof SupportedPrefabComponents, prefabName: ATTPrefabName): boolean;
+export function isSavableComponent(componentName: keyof SupportedPrefabComponents, prefabHash: ATTPrefabHash): boolean;
+export function isSavableComponent(
+  componentName: keyof SupportedPrefabComponents,
+  prefabArg: ATTPrefabName | ATTPrefabHash
+): boolean {
+  const name = typeof prefabArg === 'string' ? prefabArg : attPrefabNames[prefabArg];
+  const prefab = ATTPrefabs[name];
+  const embed = Object.entries<Embed>(prefab.embedded).find(([key]) => key.startsWith(`${name}_`))?.[1];
+
+  return typeof embed?.savables?.[componentName] !== 'undefined';
+}
diff --git a/src/utils/isUnknownComponent.test.ts b/src/utils/isUnknownComponent.test.ts
new file mode 100644
index 0000000..eda42d1
--- /dev/null
+++ b/src/utils/isUnknownComponent.test.ts
@@ -0,0 +1,26 @@
+import { Component } from '../components/Component.js';
+import { NetworkRigidbodyComponent } from '../components/NetworkRigidbodyComponent.js';
+
+import { isUnknownComponent } from './isUnknownComponent.js';
+
+describe('isUnknownComponent()', () => {
+  describe('when given a known component', () => {
+    it('returns false', () => {
+      const knownComponent = new NetworkRigidbodyComponent({ version: 1 });
+
+      const result = isUnknownComponent(knownComponent);
+
+      expect(result).toBe(false);
+    });
+  });
+
+  describe('when given an unknown component', () => {
+    it('returns true', () => {
+      const unknownComponent = new Component({ hash: 0, name: 'Unknown', version: 1 });
+
+      const result = isUnknownComponent(unknownComponent);
+
+      expect(result).toBe(true);
+    });
+  });
+});
diff --git a/src/utils/isUnknownComponent.ts b/src/utils/isUnknownComponent.ts
new file mode 100644
index 0000000..7ede618
--- /dev/null
+++ b/src/utils/isUnknownComponent.ts
@@ -0,0 +1,16 @@
+import type { Component } from '../components/Component.js';
+import type { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+
+/**
+ * Asserts if a `component` is an [`UnsupportedComponent`](https://github.com/mdingena/att-string-transcoder/tree/main/docs/UnsupportedComponent.md).
+ *
+ * @example
+ * import { isUnknownComponent } from 'att-string-transcoder';
+ *
+ * if (isUnknownComponent(component)) {
+ *   // `component` is of type `UnsupportedComponent`.
+ * }
+ */
+export function isUnknownComponent(component: Component): component is UnsupportedComponent {
+  return component.name === 'Unknown';
+}
diff --git a/src/utils/numberToBinary.ts b/src/utils/numberToBinary.ts
deleted file mode 100644
index 288768f..0000000
--- a/src/utils/numberToBinary.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const numberToBinary = (number: number): string => number.toString(2);
diff --git a/src/utils/packFloat.ts b/src/utils/packFloat.ts
deleted file mode 100644
index 07ca3af..0000000
--- a/src/utils/packFloat.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import ieee754 from 'ieee754';
-import bitwise from 'bitwise';
-import { Bit } from 'bitwise/types';
-
-export const packFloat = (number: number) => {
-  const buffer = Buffer.from(new Uint8Array(4));
-  let bits: number = 0;
-
-  ieee754.write(buffer, number, 0, true, 23, 4);
-
-  const integer = buffer.readUInt32LE(0);
-
-  for (var i = 0; i < 32; i++) {
-    const bit: Bit = bitwise.integer.getBit(integer, 31 - i);
-
-    bits = bitwise.integer.setBit(bits, 31 - i, bit);
-  }
-
-  return bits >>> 0;
-};
diff --git a/src/utils/readChildren.test.ts b/src/utils/readChildren.test.ts
new file mode 100644
index 0000000..94a77f4
--- /dev/null
+++ b/src/utils/readChildren.test.ts
@@ -0,0 +1,61 @@
+import type { PrefabChild } from '../types/PrefabChild.js';
+
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { Prefab } from '../Prefab.js';
+
+import { readChildren } from './readChildren.js';
+
+describe('readChildren()', () => {
+  let fastForwardedReader: BinaryReader;
+  const child = new Prefab('Guard');
+  const parent = new Prefab('Handle_Short', {
+    children: [
+      {
+        parentHash: 6136,
+        prefab: child
+      }
+    ]
+  });
+
+  beforeEach(() => {
+    const saveString = parent.toSaveString();
+    const [dataString] = saveString.split('|');
+
+    if (typeof dataString === 'undefined') {
+      throw new Error('Invalid test data.');
+    }
+
+    const unsignedIntegers = dataString.split(',').map(Number);
+
+    const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+    const reader = new BinaryReader(data.toBinaryString());
+
+    reader.readUnsignedInteger(); // Root prefab hash.
+    reader.readUnsignedInteger(); // SaveString bytes.
+    reader.readUnsignedInteger(); // Parent prefab hash.
+    reader.readFloat(); // Parent position X.
+    reader.readFloat(); // Parent position Y.
+    reader.readFloat(); // Parent position Z.
+    reader.readFloat(); // Parent rotation X.
+    reader.readFloat(); // Parent rotation Y.
+    reader.readFloat(); // Parent rotation Z.
+    reader.readFloat(); // Parent rotation W.
+    reader.readFloat(); // Parent scale.
+    reader.readUnsignedInteger(); // Component hash === termination hash.
+    reader.readUnsignedInteger(); // Entity hash === termination hash.
+
+    fastForwardedReader = reader;
+  });
+
+  it('returns PrefabChild[]', () => {
+    const children = readChildren(fastForwardedReader);
+
+    expect(children).toStrictEqual<PrefabChild[]>([
+      {
+        parentHash: 6136,
+        prefab: child
+      }
+    ]);
+  });
+});
diff --git a/src/utils/readChildren.ts b/src/utils/readChildren.ts
new file mode 100644
index 0000000..6caf88a
--- /dev/null
+++ b/src/utils/readChildren.ts
@@ -0,0 +1,40 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { PrefabChild } from '../types/PrefabChild.js';
+
+import { Prefab } from '../Prefab.js';
+
+/**
+ * Reads all child prefabs from the given `BinaryReader` and returns an array of `PrefabChild`.
+ *
+ * @example
+ * import { BinaryReader, readChildren } from 'att-string-transcoder';
+ *
+ * const reader = new BinaryReader('...');
+ *
+ * const componentVersions = new Map<number, number>([
+ *   [ComponentHash.NetworkRigidbody, 1],
+ *   [ComponentHash.PhysicalMaterialPart, 1],
+ *   [ComponentHash.Pickup, 2]
+ *   // etc...
+ * ]);
+ *
+ * const children = readChildren(reader, componentVersions);
+ */
+export function readChildren(reader: BinaryReader, componentVersions?: Map<number, number>): PrefabChild[] {
+  const children: PrefabChild[] = [];
+
+  const isLooping = true;
+
+  while (isLooping) {
+    const hasChild = reader.readBoolean();
+
+    if (!hasChild) break;
+
+    const parentHash = reader.readUnsignedInteger();
+    const prefab = Prefab.fromBinary(reader, componentVersions);
+
+    children.push({ parentHash, prefab });
+  }
+
+  return children;
+}
diff --git a/src/utils/readComponent.test.ts b/src/utils/readComponent.test.ts
new file mode 100644
index 0000000..741eb2a
--- /dev/null
+++ b/src/utils/readComponent.test.ts
@@ -0,0 +1,135 @@
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { Prefab } from '../Prefab.js';
+import { Component } from '../components/Component.js';
+import { NetworkRigidbodyComponent } from '../components/NetworkRigidbodyComponent.js';
+import { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { readComponent } from './readComponent.js';
+
+describe('readComponent()', () => {
+  describe('when reading a supported component', () => {
+    let fastForwardedReader: BinaryReader;
+    const componentHash = ComponentHash.NetworkRigidbody;
+    const componentName = 'NetworkRigidbody';
+    const componentVersion = 1;
+    const prefab = new Prefab('Handle_Short', {
+      components: {
+        NetworkRigidbody: new NetworkRigidbodyComponent({
+          version: componentVersion,
+          isKinematic: true,
+          velocity: { x: 1337, y: 420, z: 69 }
+        })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns a Component', () => {
+      const hash = fastForwardedReader.readUnsignedInteger();
+
+      if (hash !== componentHash) {
+        throw new Error('Invalid test data.');
+      }
+
+      const component = readComponent(fastForwardedReader, componentHash, componentName, componentVersion);
+
+      expect(component).toBeInstanceOf(Component);
+      expect(component).toBeInstanceOf(NetworkRigidbodyComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect((component as NetworkRigidbodyComponent).isKinematic).toBe(true);
+      expect((component as NetworkRigidbodyComponent).velocity).toStrictEqual({ x: 1337, y: 420, z: 69 });
+    });
+  });
+
+  describe('when reading an unsupported component', () => {
+    let fastForwardedReader: BinaryReader;
+    const componentHash = ComponentHash.RandomSpawnRectangle;
+    const componentName = 'RandomSpawnRectangle';
+    const componentVersion = 1;
+    const prefab = new Prefab('Handle_Short', {
+      components: {
+        RandomSpawnRectangle: new UnsupportedComponent({
+          hash: componentHash,
+          name: componentName,
+          version: componentVersion,
+          rawData: '00000001001101111111' as BinaryString
+        })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns an UnsupportedComponent', () => {
+      const hash = fastForwardedReader.readUnsignedInteger();
+
+      if (hash !== componentHash) {
+        throw new Error('Invalid test data.');
+      }
+
+      const component = readComponent(fastForwardedReader, componentHash, componentName, componentVersion);
+
+      expect(component).toBeInstanceOf(Component);
+      expect(component).toBeInstanceOf(UnsupportedComponent);
+      expect(component.hash).toStrictEqual(componentHash);
+      expect(component.name).toStrictEqual(componentName);
+      expect((component as UnsupportedComponent).rawData).toStrictEqual('00000001001101111111' as BinaryString);
+    });
+  });
+});
diff --git a/src/utils/readComponent.ts b/src/utils/readComponent.ts
new file mode 100644
index 0000000..7ba8bbd
--- /dev/null
+++ b/src/utils/readComponent.ts
@@ -0,0 +1,33 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { Component } from '../components/Component.js';
+
+import { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+import { supportedComponents } from '../supportedComponents.js';
+
+/**
+ * Reads next component from the given `BinaryReader` and returns a `Component` instance.
+ *
+ * @example
+ * import { BinaryReader, readChildren } from 'att-string-transcoder';
+ *
+ * const reader = new BinaryReader('...');
+ * const hash = 2290978823;
+ * const name = 'NetworkRigidbody';
+ * const version = 1;
+ *
+ * const component = readComponent(reader, hash, name, version);
+ */
+export function readComponent(reader: BinaryReader, hash: number, name: string, version: number): Component {
+  /* Get the component's data length. */
+  const dataLength = reader.readUnsignedInteger();
+
+  /* Get the component's class. */
+  const SupportedComponent = supportedComponents[name];
+
+  /* Create a component instance from the binary data string. */
+  if (typeof SupportedComponent === 'undefined') {
+    return UnsupportedComponent.fromBinary(reader, version, hash, name, dataLength);
+  } else {
+    return SupportedComponent.fromBinary(reader, version);
+  }
+}
diff --git a/src/utils/readComponents.test.ts b/src/utils/readComponents.test.ts
new file mode 100644
index 0000000..d684ae7
--- /dev/null
+++ b/src/utils/readComponents.test.ts
@@ -0,0 +1,133 @@
+import type { BinaryString } from '../types/BinaryString.js';
+
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { Prefab } from '../Prefab.js';
+import { NetworkRigidbodyComponent } from '../components/NetworkRigidbodyComponent.js';
+import { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+import { latestSupportedComponentVersions } from '../constants.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { readComponents } from './readComponents.js';
+
+const mockedUnknownComponentHash = 1337;
+const mockedUnknownComponentVersion = 42;
+
+describe('readComponents()', () => {
+  describe('when reading components', () => {
+    let fastForwardedReader: BinaryReader;
+    const firstComponentHash = ComponentHash.NetworkRigidbody;
+    const firstComponentName = 'NetworkRigidbody';
+    const firstComponentVersion = 1;
+    const secondComponentHash = ComponentHash.RandomSpawnRectangle;
+    const secondComponentName = 'RandomSpawnRectangle';
+    const secondComponentVersion = 1;
+    const thirdComponentHash = mockedUnknownComponentHash;
+    const thirdComponentName = 'Unknown';
+    const thirdComponentVersion = mockedUnknownComponentVersion;
+    const prefab = new Prefab('Handle_Short', {
+      components: {
+        NetworkRigidbody: new NetworkRigidbodyComponent({
+          version: firstComponentVersion,
+          isKinematic: true,
+          velocity: { x: 1337, y: 420, z: 69 }
+        }),
+        RandomSpawnRectangle: new UnsupportedComponent({
+          hash: secondComponentHash,
+          name: secondComponentName,
+          version: secondComponentVersion,
+          rawData: '00000001001101111111' as BinaryString
+        }),
+        Unknown: [
+          new UnsupportedComponent({
+            hash: thirdComponentHash,
+            name: thirdComponentName,
+            version: thirdComponentVersion,
+            rawData: '11110111001100010000' as BinaryString
+          })
+        ]
+      }
+    });
+
+    beforeEach(() => {
+      latestSupportedComponentVersions.set(mockedUnknownComponentHash, mockedUnknownComponentVersion);
+
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+
+      fastForwardedReader = reader;
+    });
+
+    afterEach(() => {
+      latestSupportedComponentVersions.delete(mockedUnknownComponentHash);
+    });
+
+    it('returns PrefabComponents', () => {
+      const components = readComponents(fastForwardedReader);
+
+      expect(components.NetworkRigidbody).toBeInstanceOf(NetworkRigidbodyComponent);
+      expect(components.NetworkRigidbody?.hash).toStrictEqual(firstComponentHash);
+      expect(components.NetworkRigidbody?.name).toStrictEqual(firstComponentName);
+      expect(components.NetworkRigidbody?.version).toStrictEqual(firstComponentVersion);
+      expect(components.NetworkRigidbody?.isKinematic).toBe(true);
+      expect(components.NetworkRigidbody?.velocity).toStrictEqual({ x: 1337, y: 420, z: 69 });
+
+      expect(components.RandomSpawnRectangle).toBeInstanceOf(UnsupportedComponent);
+      expect(components.RandomSpawnRectangle?.hash).toStrictEqual(secondComponentHash);
+      expect(components.RandomSpawnRectangle?.name).toStrictEqual(secondComponentName);
+      expect(components.RandomSpawnRectangle?.version).toStrictEqual(secondComponentVersion);
+      expect(components.RandomSpawnRectangle?.rawData).toStrictEqual('00000001001101111111' as BinaryString);
+
+      expect(components.Unknown[0]).toBeInstanceOf(UnsupportedComponent);
+      expect(components.Unknown[0]?.hash).toStrictEqual(thirdComponentHash);
+      expect(components.Unknown[0]?.name).toStrictEqual(thirdComponentName);
+      expect(components.Unknown[0]?.version).toStrictEqual(thirdComponentVersion);
+      expect(components.Unknown[0]?.rawData).toStrictEqual('11110111001100010000' as BinaryString);
+    });
+
+    describe('when given componentVersions and the requested version is not supported', () => {
+      beforeEach(() => {
+        /* This doesn't really happen but we need to tweak this a little for testing purposes. */
+        (latestSupportedComponentVersions as Map<number, number | undefined>).set(
+          mockedUnknownComponentHash,
+          undefined
+        );
+      });
+
+      afterEach(() => {
+        latestSupportedComponentVersions.delete(mockedUnknownComponentHash);
+      });
+
+      it('throws an error', () => {
+        const expectedToThrow = () =>
+          readComponents(fastForwardedReader, latestSupportedComponentVersions as Map<number, number>);
+        const expectedError = new Error(
+          `Could not determine version of "Unknown" (${mockedUnknownComponentHash}) component. A SaveString with chunk versioning pairs is required to read this data.`
+        );
+
+        expect(expectedToThrow).toThrowError(expectedError);
+      });
+    });
+  });
+});
diff --git a/src/utils/readComponents.ts b/src/utils/readComponents.ts
new file mode 100644
index 0000000..9274181
--- /dev/null
+++ b/src/utils/readComponents.ts
@@ -0,0 +1,60 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { Component } from '../components/Component.js';
+import type { PrefabComponents } from '../types/PrefabComponents.js';
+import type { UnknownPrefabComponents } from '../types/UnknownPrefabComponents.js';
+
+import { latestSupportedComponentVersions, terminatorHash } from '../constants.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { isUnknownComponent } from './isUnknownComponent.js';
+import { readComponent } from './readComponent.js';
+
+type KnownPrefabComponents = Record<string, Component>;
+
+/**
+ * Reads all components from the given `BinaryReader` and returns a `PrefabComponents` object.
+ *
+ * @example
+ * import { BinaryReader, readComponents } from 'att-string-transcoder';
+ *
+ * const reader = new BinaryReader('...');
+ *
+ * const versions = new Map<number, number>([
+ *   [ComponentHash.NetworkRigidbody, 1],
+ *   [ComponentHash.PhysicalMaterialPart, 1],
+ *   [ComponentHash.Pickup, 2]
+ *   // etc...
+ * ]);
+ *
+ * const component = readComponents(reader, versions);
+ */
+export function readComponents(reader: BinaryReader, versions?: Map<number, number>): PrefabComponents {
+  const components = Object.assign({} as KnownPrefabComponents, { Unknown: [] } as UnknownPrefabComponents);
+
+  const isLooping = true;
+
+  while (isLooping) {
+    const hash = reader.readUnsignedInteger();
+
+    if (hash === terminatorHash) break;
+
+    const name = ComponentHash[hash] ?? 'Unknown';
+    const version = versions?.get(hash) ?? latestSupportedComponentVersions.get(hash);
+
+    if (typeof version === 'undefined') {
+      throw new Error(
+        `Could not determine version of "${name}" (${hash}) component. A SaveString with chunk versioning pairs is required to read this data.`
+      );
+    }
+
+    const component = readComponent(reader, hash, name, version);
+
+    if (isUnknownComponent(component)) {
+      components.Unknown.push(component);
+    } else {
+      components[name] = component;
+    }
+  }
+
+  return components;
+}
diff --git a/src/utils/readEntities.test.ts b/src/utils/readEntities.test.ts
new file mode 100644
index 0000000..4706322
--- /dev/null
+++ b/src/utils/readEntities.test.ts
@@ -0,0 +1,77 @@
+import { BinaryData } from '../BinaryData.js';
+import { BinaryReader } from '../BinaryReader.js';
+import { Entity } from '../Entity.js';
+import { Prefab } from '../Prefab.js';
+
+import { readEntities } from './readEntities.js';
+
+describe('readEntities()', () => {
+  describe('when reading entities', () => {
+    let fastForwardedReader: BinaryReader;
+    const firstEntityHash = 6136;
+    const firstEntityName = 'Slot_Multi';
+    const secondEntityHash = 23002;
+    const secondEntityName = 'Unknown';
+    const prefabName = 'Handle_Short';
+    const prefab = new Prefab(prefabName, {
+      entities: {
+        Slot_Multi_6136: new Entity<typeof prefabName>(`${firstEntityName}_${firstEntityHash}`, {
+          hash: firstEntityHash,
+          isAlive: true
+        }),
+        /* @ts-expect-error Add in an unknown entity. */
+        Unknown_23002: new Entity(secondEntityName, {
+          hash: secondEntityHash,
+          isAlive: false
+        })
+      }
+    });
+
+    beforeEach(() => {
+      const saveString = prefab.toSaveString();
+      const [dataString] = saveString.split('|');
+
+      if (typeof dataString === 'undefined') {
+        throw new Error('Invalid test data.');
+      }
+
+      const unsignedIntegers = dataString.split(',').map(Number);
+
+      const data = BinaryData.fromUnsignedIntegerArray(unsignedIntegers);
+      const reader = new BinaryReader(data.toBinaryString());
+
+      reader.readUnsignedInteger(); // Root prefab hash.
+      reader.readUnsignedInteger(); // SaveString bytes.
+      reader.readUnsignedInteger(); // Parent prefab hash.
+      reader.readFloat(); // Parent position X.
+      reader.readFloat(); // Parent position Y.
+      reader.readFloat(); // Parent position Z.
+      reader.readFloat(); // Parent rotation X.
+      reader.readFloat(); // Parent rotation Y.
+      reader.readFloat(); // Parent rotation Z.
+      reader.readFloat(); // Parent rotation W.
+      reader.readFloat(); // Parent scale.
+      reader.readUnsignedInteger(); // Component hash === termination hash.
+
+      fastForwardedReader = reader;
+    });
+
+    it('returns PrefabEntities', () => {
+      const entities = readEntities(fastForwardedReader, prefabName);
+
+      expect(entities['Slot_Multi_6136']).toBeInstanceOf(Entity);
+      expect(entities['Slot_Multi_6136']?.hash).toStrictEqual(firstEntityHash);
+      expect(entities['Slot_Multi_6136']?.name).toStrictEqual(firstEntityName);
+      expect(entities['Slot_Multi_6136']?.isAlive).toBe(true);
+
+      /* @ts-expect-error Access unknown entity. */
+      expect(entities['Unknown_23002']).toBeInstanceOf(Entity);
+      /* @ts-expect-error Access unknown entity. */
+      expect(entities['Unknown_23002']?.hash).toStrictEqual(secondEntityHash);
+      /* @ts-expect-error Access unknown entity. */
+      expect(entities['Unknown_23002']?.name).toStrictEqual(secondEntityName);
+      /* @ts-expect-error Access unknown entity. */
+      expect(entities['Unknown_23002']?.isAlive).toBe(false);
+    });
+  });
+});
diff --git a/src/utils/readEntities.ts b/src/utils/readEntities.ts
new file mode 100644
index 0000000..e73bf2b
--- /dev/null
+++ b/src/utils/readEntities.ts
@@ -0,0 +1,62 @@
+import type { BinaryReader } from '../BinaryReader.js';
+import type { ATTPrefabName } from '../types/ATTPrefabName.js';
+import type { EntityKey } from '../types/EntityKey.js';
+import type { PrefabEntities } from '../types/PrefabEntities.js';
+
+import { Entity } from '../Entity.js';
+import { terminatorHash } from '../constants.js';
+import { ATTPrefabs } from '../types/ATTPrefabs.js';
+
+/**
+ * Reads all entities from the given `BinaryReader` and returns a `PrefabEntities` object.
+ *
+ * @example
+ * import { BinaryReader, readEntities, type ATTPrefabName } from 'att-string-transcoder';
+ *
+ * const reader = new BinaryReader('...');
+ * const prefabName = 'Handle_Short' as ATTPrefabName;
+ *
+ * const componentVersions = new Map<number, number>([
+ *   [ComponentHash.NetworkRigidbody, 1],
+ *   [ComponentHash.PhysicalMaterialPart, 1],
+ *   [ComponentHash.Pickup, 2]
+ *   // etc...
+ * ]);
+ *
+ * const component = readEntities(reader, prefabName, componentVersions);
+ */
+export function readEntities<TPrefabName extends ATTPrefabName>(
+  reader: BinaryReader,
+  prefabName: TPrefabName,
+  componentVersions?: Map<number, number>
+): PrefabEntities<TPrefabName> {
+  const entities: PrefabEntities<TPrefabName> = {};
+
+  const isLooping = true;
+
+  while (isLooping) {
+    const hash = reader.readUnsignedInteger();
+
+    if (hash === terminatorHash) break;
+
+    /* Get the entity's data length and ignore it. */
+    reader.readUnsignedInteger();
+
+    const entity = Object.values<{
+      hash: number;
+      name: string;
+      savables: Record<string, { hash: number; name: string }>;
+    }>(ATTPrefabs[prefabName].embedded).find(attPrefabEntity => attPrefabEntity.hash === hash);
+
+    const name = entity?.name ?? 'Unknown';
+    const key = `${name}_${hash}` as EntityKey<TPrefabName>;
+
+    entities[key] = Entity.fromBinary<typeof prefabName>(reader, {
+      hash,
+      key: name === 'Unknown' ? name : (key as string),
+      componentVersions
+    });
+  }
+
+  return entities;
+}
diff --git a/src/utils/uIntToBinary.ts b/src/utils/uIntToBinary.ts
deleted file mode 100644
index 5a9e39b..0000000
--- a/src/utils/uIntToBinary.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { numberToBinary } from './numberToBinary';
-
-export const uIntToBinary = (uInt: number): string => numberToBinary(uInt).padStart(32, '0');
diff --git a/src/utils/uLongToBinary.ts b/src/utils/uLongToBinary.ts
deleted file mode 100644
index c87a093..0000000
--- a/src/utils/uLongToBinary.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { numberToBinary } from './numberToBinary';
-
-export const uLongToBinary = (number: number): string => {
-  const binary = numberToBinary(number).padStart(64, '0');
-
-  return `${binary.slice(32)}${binary.slice(0, 32)}`;
-};
diff --git a/src/utils/unpackFloat.ts b/src/utils/unpackFloat.ts
deleted file mode 100644
index 4cd50d3..0000000
--- a/src/utils/unpackFloat.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import ieee754 from 'ieee754';
-
-/**
- * Convert IEEE754 integer to JavaScript number.
- * Thanks to https://github.com/edencomputing/attprefabulator/
- */
-export const unpackFloat = (uInt: number) => {
-  const buffer = Buffer.from(new Uint8Array(4));
-
-  buffer.writeUInt32LE(uInt);
-
-  return ieee754.read(buffer, 0, true, 23, 4);
-};
diff --git a/src/utils/writeChildren.test.ts b/src/utils/writeChildren.test.ts
new file mode 100644
index 0000000..c2bc2c0
--- /dev/null
+++ b/src/utils/writeChildren.test.ts
@@ -0,0 +1,31 @@
+import type { PrefabChild } from '../types/PrefabChild.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Prefab } from '../Prefab.js';
+
+import { writeChildren } from './writeChildren.js';
+
+describe('writeChildren()', () => {
+  let prefabChildren: PrefabChild[];
+
+  beforeEach(() => {
+    prefabChildren = [
+      { parentHash: 1337, prefab: new Prefab('Phantom_Guard') },
+      { parentHash: 420, prefab: new Prefab('Phantom_Guard') },
+      { parentHash: 69, prefab: new Prefab('Phantom_Guard') }
+    ];
+  });
+
+  it('stores PrefabChildren in the given BinaryWriter', () => {
+    const expectedData =
+      '1000000000000000000000101001110010000000000000000000110110001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000011010010000000000000000000001101100011100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111000000000000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000001000101000000000000000000011011000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
+
+    const writer = new BinaryWriter();
+
+    writeChildren(writer, prefabChildren, new Map());
+
+    const data = writer.flush();
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
diff --git a/src/utils/writeChildren.ts b/src/utils/writeChildren.ts
new file mode 100644
index 0000000..bd39063
--- /dev/null
+++ b/src/utils/writeChildren.ts
@@ -0,0 +1,55 @@
+import type { BinaryWriter } from '../BinaryWriter.js';
+import type { PrefabChild } from '../types/PrefabChild.js';
+
+/**
+ * Writes given child prefabs to the given `BinaryWriter`.
+ *
+ * @example
+ * import { BinaryWriter, writeChildren } from 'att-string-transcoder';
+ *
+ * const writer = new BinaryWriter();
+ *
+ * const children = [
+ *   {
+ *     parentHash: 0,
+ *     prefab: new Prefab('Guard')
+ *   }
+ * ];
+ *
+ * const componentVersions = new Map<number, number>([
+ *   [ComponentHash.NetworkRigidbody, 1],
+ *   [ComponentHash.PhysicalMaterialPart, 1],
+ *   [ComponentHash.Pickup, 2]
+ *   // etc...
+ * ]);
+ *
+ * writeChildren(writer, children, componentVersions);
+ */
+export function writeChildren(
+  writer: BinaryWriter,
+  children: PrefabChild[],
+  componentVersions: Map<number, number>
+): void {
+  for (const { parentHash, prefab } of children) {
+    /**
+     * @property {boolean} hasChild
+     */
+    writer.writeBoolean(true);
+
+    /**
+     * @property {number} parentHash
+     */
+    writer.writeUnsignedInteger(parentHash);
+
+    /**
+     * @property {Prefab} prefab
+     */
+    const data = prefab.toBinary(componentVersions);
+    writer.writeBits(data);
+  }
+
+  /**
+   * @property {boolean} terminatorBit
+   */
+  writer.writeBoolean(false);
+}
diff --git a/src/utils/writeComponents.test.ts b/src/utils/writeComponents.test.ts
new file mode 100644
index 0000000..1864da2
--- /dev/null
+++ b/src/utils/writeComponents.test.ts
@@ -0,0 +1,70 @@
+import type { BinaryString } from '../types/BinaryString.js';
+import type { PrefabComponents } from '../types/PrefabComponents.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { NetworkRigidbodyComponent } from '../components/NetworkRigidbodyComponent.js';
+import { UnsupportedComponent } from '../components/UnsupportedComponent.js';
+import { ComponentHash } from '../types/ComponentHash.js';
+
+import { writeComponents } from './writeComponents.js';
+
+const mockedUnknownComponentHash = 1337;
+const mockedUnknownComponentVersion = 42;
+
+describe('writeComponents()', () => {
+  const firstComponentHash = ComponentHash.NetworkRigidbody;
+  const firstComponentVersion = 1;
+  const secondComponentHash = ComponentHash.RandomSpawnRectangle;
+  const secondComponentName = 'RandomSpawnRectangle';
+  const secondComponentVersion = 1;
+  const thirdComponentHash = mockedUnknownComponentHash;
+  const thirdComponentName = 'Unknown';
+  const thirdComponentVersion = mockedUnknownComponentVersion;
+
+  let prefabComponents: PrefabComponents;
+
+  beforeEach(() => {
+    prefabComponents = {
+      NetworkRigidbody: new NetworkRigidbodyComponent({
+        version: firstComponentVersion,
+        isKinematic: true,
+        velocity: { x: 1337, y: 420, z: 69 }
+      }),
+      RandomSpawnRectangle: new UnsupportedComponent({
+        hash: secondComponentHash,
+        name: secondComponentName,
+        version: secondComponentVersion,
+        rawData: '00000001001101111111' as BinaryString
+      }),
+      Unknown: [
+        new UnsupportedComponent({
+          hash: thirdComponentHash,
+          name: thirdComponentName,
+          version: thirdComponentVersion,
+          rawData: '11110111001100010000' as BinaryString
+        })
+      ]
+    };
+  });
+
+  it('stores PrefabComponents in the given BinaryWriter', () => {
+    const expectedData =
+      '1000100010001101100100000000011100000000000000000000000110100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111000000000000000000000001001000100101001110010000000000000010000111101001000000000000000000100001010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010111000110111111010100011110001000000000000000000000000000101000000000100110111111100000000000000000000010100111001000000000000000000000000000101001111011100110001000000000000000000000000000000000000';
+
+    const writer = new BinaryWriter();
+
+    writeComponents(
+      writer,
+      prefabComponents,
+      new Map([
+        [firstComponentHash, firstComponentVersion],
+        [secondComponentHash, secondComponentVersion],
+        [thirdComponentHash, thirdComponentVersion]
+      ])
+    );
+
+    const data = writer.flush();
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
diff --git a/src/utils/writeComponents.ts b/src/utils/writeComponents.ts
new file mode 100644
index 0000000..ed14839
--- /dev/null
+++ b/src/utils/writeComponents.ts
@@ -0,0 +1,53 @@
+import type { BinaryWriter } from '../BinaryWriter.js';
+import type { PrefabComponents } from '../types/PrefabComponents.js';
+
+import { terminatorHash } from '../constants.js';
+
+/**
+ * Writes given components to the given `BinaryWriter`.
+ *
+ * @example
+ * import { BinaryWriter, writeComponents } from 'att-string-transcoder';
+ *
+ * const writer = new BinaryWriter();
+ *
+ * const components = {
+ *   NetworkRigidbody: new NetworkRigidbody({ version: 1 }),
+ *   Unknown: []
+ * };
+ *
+ * const versions = new Map<number, number>([
+ *   [ComponentHash.NetworkRigidbody, 1],
+ *   [ComponentHash.PhysicalMaterialPart, 1],
+ *   [ComponentHash.Pickup, 2]
+ *   // etc...
+ * ]);
+ *
+ * writeComponents(writer, components, versions);
+ */
+export function writeComponents(
+  writer: BinaryWriter,
+  components: PrefabComponents,
+  versions: Map<number, number>
+): void {
+  for (const component of Object.values(components)) {
+    if (Array.isArray(component)) {
+      for (const unknownComponent of component) {
+        /**
+         * @property {Component} unknownComponent
+         */
+        unknownComponent.write(writer, versions.get(unknownComponent.hash));
+      }
+    } else {
+      /**
+       * @property {Component} unknownComponent
+       */
+      component.write(writer, versions.get(component.hash));
+    }
+  }
+
+  /**
+   * @property {number} terminatorHash
+   */
+  writer.writeUnsignedInteger(terminatorHash);
+}
diff --git a/src/utils/writeEntities.test.ts b/src/utils/writeEntities.test.ts
new file mode 100644
index 0000000..97cc119
--- /dev/null
+++ b/src/utils/writeEntities.test.ts
@@ -0,0 +1,40 @@
+import type { PrefabEntities } from '../types/PrefabEntities.js';
+
+import { BinaryWriter } from '../BinaryWriter.js';
+import { Entity } from '../Entity.js';
+
+import { writeEntities } from './writeEntities.js';
+
+describe('writeEntities()', () => {
+  const secondEntityHash = 23002;
+  const secondEntityKey = 'Unknown';
+
+  let prefabEntities: PrefabEntities<'Torch'>;
+
+  beforeEach(() => {
+    prefabEntities = {
+      Fire_30100: new Entity('Fire_30100', {
+        hash: 30100,
+        isAlive: true
+      }),
+      /* @ts-expect-error Add in an unknown entity. */
+      Unknown_23002: new Entity(secondEntityKey, {
+        hash: secondEntityHash,
+        isAlive: false
+      })
+    };
+  });
+
+  it('stores PrefabEntities in the given BinaryWriter', () => {
+    const expectedData =
+      '0000000000000000011101011001010000000000000000000000000000100001100000000000000000000000000000000000000000000000001011001110110100000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000';
+
+    const writer = new BinaryWriter();
+
+    writeEntities(writer, prefabEntities, new Map());
+
+    const data = writer.flush();
+
+    expect(data).toStrictEqual(expectedData);
+  });
+});
diff --git a/src/utils/writeEntities.ts b/src/utils/writeEntities.ts
new file mode 100644
index 0000000..a5e8c66
--- /dev/null
+++ b/src/utils/writeEntities.ts
@@ -0,0 +1,44 @@
+import type { BinaryWriter } from '../BinaryWriter.js';
+import type { ATTPrefabName } from '../types/ATTPrefabName.js';
+import type { PrefabEntities } from '../types/PrefabEntities.js';
+
+import { terminatorHash } from '../constants.js';
+
+/**
+ * Writes given entities to the given `BinaryWriter`.
+ *
+ * @example
+ * import { BinaryWriter, Entity, writeEntities } from 'att-string-transcoder';
+ *
+ * const writer = new BinaryWriter();
+ *
+ * const entities = {
+ *   Fire_30100: new Entity<'Torch'>('Fire_30100')
+ * };
+ *
+ * const componentVersions = new Map<number, number>([
+ *   [ComponentHash.NetworkRigidbody, 1],
+ *   [ComponentHash.PhysicalMaterialPart, 1],
+ *   [ComponentHash.Pickup, 2]
+ *   // etc...
+ * ]);
+ *
+ * writeEntities(writer, entities, componentVersions);
+ */
+export function writeEntities<TPrefabName extends ATTPrefabName>(
+  writer: BinaryWriter,
+  entities: PrefabEntities<TPrefabName>,
+  componentVersions: Map<number, number>
+): void {
+  for (const entity of Object.values(entities)) {
+    /**
+     * @property {Entity} entity
+     */
+    entity.write(writer, componentVersions);
+  }
+
+  /**
+   * @property {number} terminatorHash
+   */
+  writer.writeUnsignedInteger(terminatorHash);
+}
diff --git a/tests/createString.test.ts b/tests/createString.test.ts
deleted file mode 100644
index 337fc1a..0000000
--- a/tests/createString.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { createString } from '../build';
-import { handle, litGrassClump } from './data/unencodedPrefabObjects';
-import { grassClumpOnFire, shortHandleWithLargeGuardAndLargeBlade } from './data/encodedPrefabObjects';
-
-describe('createString', () => {
-  it('should encode a prefab object', () => {
-    const encodedPrefab = createString(handle);
-
-    expect(encodedPrefab).toStrictEqual(shortHandleWithLargeGuardAndLargeBlade);
-  });
-
-  it('should create a version string', () => {
-    const encodedPrefab = createString(litGrassClump);
-
-    expect(encodedPrefab).toStrictEqual(grassClumpOnFire);
-  });
-});
diff --git a/tests/data/decodedStrings.ts b/tests/data/decodedStrings.ts
deleted file mode 100644
index b538724..0000000
--- a/tests/data/decodedStrings.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-export const decodedEmptyFlask = {
-  hash: 23644,
-  size: 1392,
-  prefab: {
-    prefabObject: {
-      hash: 23644,
-      position: {
-        x: -699.1250610351562,
-        y: 128.15176391601562,
-        z: 98.96036529541016
-      },
-      rotation: {
-        x: -0.00007028286927379668,
-        y: -0.06372569501399994,
-        z: -0.0011925859143957496,
-        w: 0.9979667663574219
-      },
-      scale: 1.0000009536743164
-    },
-    components: {
-      Unknown: [],
-      NetworkRigidbody: {
-        position: {
-          x: -699.1250610351562,
-          y: 128.15176391601562,
-          z: 98.96036529541016
-        },
-        rotation: {
-          x: -0.00007028286927379668,
-          y: -0.06372569501399994,
-          z: -0.0011925859143957496,
-          w: 0.9979667663574219
-        },
-        isKinematic: false,
-        isServerSleeping: true,
-        velocity: {
-          x: 0,
-          y: 0,
-          z: 0
-        },
-        angularVelocity: {
-          x: 0,
-          y: 0,
-          z: 0
-        }
-      },
-      Pickup: {
-        lastInteractorPlayerId: 1965324787
-      },
-      LiquidContainer: {
-        canAddTo: false,
-        canRemoveFrom: true,
-        contentLevel: 0,
-        hasContent: false,
-        isCustom: false,
-        presetHash: 0,
-        customData: null
-      },
-      BasicDecay: {
-        isDisabled: false,
-        timelineEntry: 37654637031400
-      }
-    },
-    embeddedEntities: {
-      Unknown: [
-        {
-          hash: 21290,
-          isAlive: true,
-          components: {
-            Unknown: [],
-            Pickup: {
-              lastInteractorPlayerId: 1965324787
-            }
-          }
-        }
-      ]
-    },
-    childPrefabs: []
-  }
-};
diff --git a/tests/data/encodedPrefabObjects.ts b/tests/data/encodedPrefabObjects.ts
deleted file mode 100644
index efee988..0000000
--- a/tests/data/encodedPrefabObjects.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const shortHandleWithLargeGuardAndLargeBlade =
-  '42230,252,42230,3291430912,1124086579,1120403456,0,0,0,1065353216,1065353216,2290978823,418,3291430912,1124086579,1120403456,0,0,0,1065353216,0,0,0,0,0,0,0,0,536871679,1163,0,0,0,0,0,0,133169152,133169152,34023564,2684354564,2523,1307670851,3758096388,126122721,1073741824,0,268438699,2147487155,3221225472,0,0,0,0,0,66584576,66584576,17011782,1342177282,1968,3875060897,4026531842,63061360,2684354560,0,0,|3,2290978823,1,272188517,1,1871432223,1,';
-export const grassClumpOnFire =
-  '57872,80,57872,0,0,0,0,0,0,1065353216,1065353216,0,30100,194,4202164032,48,3221225472,343781376,1836894,0,0,0,|1,4109360768,2,';
diff --git a/tests/data/encodedStrings.ts b/tests/data/encodedStrings.ts
deleted file mode 100644
index 16a0620..0000000
--- a/tests/data/encodedStrings.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export const encodedEmptyFlask =
-  '23644,174,23644,3291400193,1124083418,1120267189,3096667348,3179446942,3130806411,1065319104,1065353224,2290978823,418,3291400193,1124083418,1120267189,3096667348,3179446942,3130806411,1065319104,1073741824,0,0,0,0,0,363610349,2147483656,1028202108,4266048908,3221225489,1476395008,0,63251750,2751463424,2183611311,3892314146,1056964608,83,704643072,2175490177,3674210304,276468284,4185915392,0,0,|150,1908922854,1,159391088,1,3801256786,3,272188517,1,237360636,2,391977879,2,277505782,2,22446553,2,403040752,2,2617495528,1,2978042925,1,2801168996,2,2495475500,2,1176706580,2,1001395212,2,1874870249,2,3230087383,1,2498617949,1,1714180166,2,3109677933,2,1509838052,1,320224849,1,2272630171,1,1217391130,1,276353327,1,1823429789,1,3402094521,1,751359624,1,3608460219,1,1390862571,1,1085701614,1,3445325106,1,2126500253,1,2624099526,1,1871432223,1,3373651539,1,654225716,1,1454441398,1,3704379512,1,3257374625,1,2262399392,2,309083880,1,586602603,1,1934129787,1,3146178080,1,661497638,1,2293737711,1,496827038,1,2912807649,1,2190886200,1,2069630919,1,3920618075,1,3665939353,1,3901697682,1,1211178616,1,2951515968,1,1588536425,1,2576456808,1,2127962967,1,70871065,1,1063725326,1,3101665521,1,2815374842,1,4081488368,1,3820454400,4,1624211074,1,7704646,1,830106687,1,1651678475,1,2400796504,1,910018632,2,4144776006,3,566175523,1,2975913730,1,875684520,1,2169673426,1,3450348902,1,1233775263,1,43510150,2,1645673210,2,3431876266,1,4095875831,1,2314081177,1,2590537994,2,2443660852,1,967932020,1,3171294583,1,3751351177,1,1257282635,2,200292695,3,2700376822,1,3188272159,1,3245685963,1,2120963769,1,392344172,1,1391720462,2,2610542999,1,1081247904,1,2880587164,1,2563434699,1,2253011220,1,2814234626,1,1964978567,1,1228539097,1,2026743731,1,3538443740,1,634164392,5,2759613175,1,3642863935,2,4134534481,1,1931537627,1,259381630,1,3932346318,1,2978388169,1,1431397437,2,3070493599,2,3588929783,1,3640332570,1,1787084913,4,1454955908,1,788405183,1,2563567105,2,766675725,1,2882590463,1,1499506132,1,205333986,1,4179293747,1,3236280681,3,902024186,1,2450553269,1,2629079826,1,963907309,1,1753993206,2,1923918202,2,1776498660,3,3638500874,2,1098050191,3,3084373371,1,2833060406,1,1587058252,1,2592242915,2,34507654,1,1962842866,1,4282337604,1,3561515449,1,2290978823,1,3674519521,1,2081565440,1,4109360768,2,3457519710,2,';
diff --git a/tests/data/unencodedPrefabObjects.ts b/tests/data/unencodedPrefabObjects.ts
deleted file mode 100644
index bf1ab5e..0000000
--- a/tests/data/unencodedPrefabObjects.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Prefab, PrefabHash, PhysicalMaterialPartHash } from '../../build';
-
-const position = {
-  x: -701,
-  y: 128.2,
-  z: 100
-};
-
-export const blade: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Large_Longsword_Blade
-  },
-  components: {
-    PhysicalMaterialPart: {
-      materialHash: PhysicalMaterialPartHash.EvinonSteelAlloy
-    },
-    DurabilityModule: {
-      integrity: 0.01
-    }
-  }
-};
-
-export const guard: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Large_Guard_Rectangle
-  },
-  components: {
-    PhysicalMaterialPart: {
-      materialHash: PhysicalMaterialPartHash.Copper
-    },
-    DurabilityModule: {
-      integrity: 0.01
-    }
-  },
-  childPrefabs: [
-    {
-      parentHash: 51896, // @todo extend PrefabEmbeddedEntityHash
-      prefab: blade
-    }
-  ]
-};
-
-export const handle: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Handle_Short,
-    position
-  },
-  components: {
-    NetworkRigidbody: {
-      position
-    }
-  },
-  childPrefabs: [
-    {
-      parentHash: 6136, // @todo extend PrefabEmbeddedEntityHash
-      prefab: guard
-    }
-  ]
-};
-
-export const litGrassClump: Prefab = {
-  prefabObject: {
-    hash: PrefabHash.Grass_Clump
-  },
-  embeddedEntities: {
-    Fire: {
-      components: {
-        HeatSourceBase: {}
-      }
-    }
-  }
-};
diff --git a/tests/decodeString.test.ts b/tests/decodeString.test.ts
deleted file mode 100644
index 59cdcd8..0000000
--- a/tests/decodeString.test.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { decodeString } from '../build';
-import { encodedEmptyFlask } from './data/encodedStrings';
-import { decodedEmptyFlask } from './data/decodedStrings';
-
-describe('decodeString', () => {
-  it('should decode a string of UInts', () => {
-    const decodedString = decodeString(encodedEmptyFlask);
-
-    expect(decodedString).toStrictEqual(decodedEmptyFlask);
-  });
-});
diff --git a/tsconfig-cjs.json b/tsconfig-cjs.json
new file mode 100644
index 0000000..c65069c
--- /dev/null
+++ b/tsconfig-cjs.json
@@ -0,0 +1,11 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "module": "commonjs",
+    "moduleResolution": "Node",
+    "outDir": "dist/cjs",
+    "verbatimModuleSyntax": false
+  },
+  "include": ["src/**/*"],
+  "exclude": ["src/**/*.test.*"]
+}
diff --git a/tsconfig-esm.json b/tsconfig-esm.json
new file mode 100644
index 0000000..77f3e41
--- /dev/null
+++ b/tsconfig-esm.json
@@ -0,0 +1,12 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "declaration": true,
+    "declarationDir": "dist/types",
+    "declarationMap": false,
+    "outDir": "dist/esm",
+    "verbatimModuleSyntax": true
+  },
+  "include": ["src/**/*"],
+  "exclude": ["src/**/*.test.*"]
+}
diff --git a/tsconfig.json b/tsconfig.json
index 61fb911..94b5c84 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,16 +1,26 @@
 {
   "compilerOptions": {
+    "allowJs": false,
+    "allowUnreachableCode": false,
+    "allowUnusedLabels": false,
     "esModuleInterop": true,
+    "exactOptionalPropertyTypes": true,
     "forceConsistentCasingInFileNames": true,
-    "module": "commonjs",
-    "declaration": true,
-    "declarationMap": true,
-    "sourceMap": true,
-    "outDir": "./build",
+    "lib": ["ES2023"],
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",
+    "noFallthroughCasesInSwitch": true,
+    "noImplicitOverride": true,
+    "noImplicitReturns": true,
+    "noPropertyAccessFromIndexSignature": true,
+    "noUncheckedIndexedAccess": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
     "skipLibCheck": true,
+    "sourceMap": false,
     "strict": true,
-    "lib": ["es2017"],
-    "target": "es6"
+    "target": "ESNext",
+    "verbatimModuleSyntax": true
   },
-  "include": ["./src/**/*", "./decodeString.js"]
+  "include": ["src/**/*", "vitest.config.ts"]
 }
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000..748a8a5
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,22 @@
+import { defineConfig } from 'vitest/config';
+
+const srcFileGlob = '*.ts';
+const testFileGlob = '*.test.ts';
+
+export default defineConfig({
+  test: {
+    globals: true,
+    environment: 'node',
+    include: [`src/**/${testFileGlob}`],
+    watchExclude: ['**/node_modules/*', '**/dist/*'],
+    coverage: {
+      enabled: true,
+      all: true,
+      reportOnFailure: false,
+      skipFull: true,
+      100: true,
+      include: [`src/**/${srcFileGlob}`],
+      exclude: [`**/${testFileGlob}`, '**/*.d.ts', 'src/index.ts', 'src/types/*']
+    }
+  }
+});
