master 05c3434ceed4 cached
263 files
1.1 MB
272.7k tokens
2384 symbols
1 requests
Download .txt
Showing preview only (1,275K chars total). Download the full file or copy to clipboard to get everything.
Repository: Minestom/VanillaReimplementation
Branch: master
Commit: 05c3434ceed4
Files: 263
Total size: 1.1 MB

Directory structure:
gitextract_r6lz745n/

├── .github/
│   └── CONTRIBUTING.md
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── block-update-system/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           ├── BlockUpdateFeature.java
│                           ├── blockupdatesystem/
│                           │   ├── BlockUpdatable.java
│                           │   ├── BlockUpdateInfo.java
│                           │   └── BlockUpdateManager.java
│                           └── randomticksystem/
│                               ├── RandomTickManager.java
│                               └── RandomTickable.java
├── blocks/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── blocks/
│                               ├── VanillaBlockBehaviour.java
│                               ├── VanillaBlockLoot.java
│                               ├── VanillaBlocks.java
│                               ├── VanillaBlocksFeature.java
│                               └── behaviours/
│                                   ├── BedBlockBehaviour.java
│                                   ├── CakeBlockBehaviour.java
│                                   ├── ChestBlockBehaviour.java
│                                   ├── ConcretePowderBlockBehaviour.java
│                                   ├── EndPortalBlockBehaviour.java
│                                   ├── EnderChestBlockBehaviour.java
│                                   ├── FireBlockBehaviour.java
│                                   ├── GravityBlockBehaviour.java
│                                   ├── InventoryBlockBehaviour.java
│                                   ├── JukeboxBlockBehaviour.java
│                                   ├── NetherPortalBlockBehaviour.java
│                                   ├── TNTBlockBehaviour.java
│                                   ├── TrappedChestBlockBehaviour.java
│                                   ├── chestlike/
│                                   │   ├── BlockInventory.java
│                                   │   ├── BlockItems.java
│                                   │   └── DoubleChestInventory.java
│                                   ├── oxidisable/
│                                   │   ├── OxidatableBlockBehaviour.java
│                                   │   ├── OxidatedBlockBehaviour.java
│                                   │   ├── OxygenSensitive.java
│                                   │   ├── WaxableBlockBehaviour.java
│                                   │   └── WaxedBlockBehaviour.java
│                                   └── recipe/
│                                       ├── BlastingFurnaceBehaviour.java
│                                       ├── CampfireBehaviour.java
│                                       ├── CraftingTableBehaviour.java
│                                       ├── FurnaceBehaviour.java
│                                       ├── SmithingTableBehaviour.java
│                                       ├── SmokerBehaviour.java
│                                       └── StonecutterBehaviour.java
├── build.gradle.kts
├── commands/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── commands/
│                               ├── DifficultyCommand.java
│                               ├── ForceloadCommand.java
│                               ├── GamemodeCommand.java
│                               ├── HelpCommand.java
│                               ├── MeCommand.java
│                               ├── SaveAllCommand.java
│                               ├── StopCommand.java
│                               ├── VanillaCommands.java
│                               └── VanillaCommandsFeature.java
├── core/
│   ├── build.gradle.kts
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── net/
│       │   │       └── minestom/
│       │   │           └── vanilla/
│       │   │               ├── VanillaRegistry.java
│       │   │               ├── VanillaReimplementation.java
│       │   │               ├── VanillaReimplementationImpl.java
│       │   │               ├── dimensions/
│       │   │               │   └── VanillaDimensionTypes.java
│       │   │               ├── events/
│       │   │               │   ├── BlastingFurnaceTickEvent.java
│       │   │               │   ├── FurnaceTickEvent.java
│       │   │               │   └── SmokerTickEvent.java
│       │   │               ├── files/
│       │   │               │   ├── ByteArray.java
│       │   │               │   ├── CacheFileSystem.java
│       │   │               │   ├── DynamicFileSystem.java
│       │   │               │   ├── FileSystem.java
│       │   │               │   ├── FileSystemImpl.java
│       │   │               │   ├── FileSystemMappers.java
│       │   │               │   ├── FileSystemUtil.java
│       │   │               │   ├── LazyFileSystem.java
│       │   │               │   ├── MappedFileSystem.java
│       │   │               │   └── PathFileSystem.java
│       │   │               ├── instance/
│       │   │               │   ├── SetupVanillaInstanceEvent.java
│       │   │               │   └── VanillaExplosion.java
│       │   │               ├── inventory/
│       │   │               │   └── InventoryManipulation.java
│       │   │               ├── logging/
│       │   │               │   ├── Color.java
│       │   │               │   ├── Level.java
│       │   │               │   ├── Loading.java
│       │   │               │   ├── LoadingBar.java
│       │   │               │   ├── LoadingImpl.java
│       │   │               │   ├── Logger.java
│       │   │               │   ├── LoggerImpl.java
│       │   │               │   ├── LoggingLoadingBar.java
│       │   │               │   ├── SLF4JCompatibilityLayer.java
│       │   │               │   ├── SLF4JServiceProvider.java
│       │   │               │   └── StatusUpdater.java
│       │   │               ├── system/
│       │   │               │   ├── EnderChestSystem.java
│       │   │               │   ├── NetherPortal.java
│       │   │               │   ├── RayFastManager.java
│       │   │               │   ├── ServerProperties.java
│       │   │               │   └── nether/
│       │   │               │       ├── EntityEnterNetherPortalEvent.java
│       │   │               │       ├── NetherPortalTeleportEvent.java
│       │   │               │       └── NetherPortalUpdateEvent.java
│       │   │               ├── tag/
│       │   │               │   └── Tags.java
│       │   │               └── utils/
│       │   │                   ├── DependencySorting.java
│       │   │                   ├── JavaUtils.java
│       │   │                   ├── MathUtils.java
│       │   │                   ├── MinestomUtils.java
│       │   │                   └── ZipUtils.java
│       │   └── resources/
│       │       └── META-INF/
│       │           └── services/
│       │               └── org.tinylog.writers.Writer
│       └── test/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── files/
│                               └── FileSystemTests.java
├── crafting/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── crafting/
│                               ├── CraftingFeature.java
│                               ├── CraftingRecipes.java
│                               └── Recipe.java
├── datapack/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── datapack/
│                               └── Datapacks.java
├── datapack-loading/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── datapack/
│                               ├── Datapack.java
│                               ├── DatapackLoader.java
│                               ├── DatapackLoadingFeature.java
│                               ├── DatapackUtils.java
│                               ├── advancement/
│                               │   └── Advancement.java
│                               ├── dimension/
│                               │   └── DimensionType.java
│                               ├── json/
│                               │   ├── JsonUtils.java
│                               │   ├── ListLike.java
│                               │   └── Optional.java
│                               ├── loot/
│                               │   ├── LootTable.java
│                               │   ├── NBTPath.java
│                               │   ├── NBTPathImpl.java
│                               │   ├── context/
│                               │   │   ├── ContextGroups.java
│                               │   │   ├── LootContext.java
│                               │   │   ├── MappedTraitImpl.java
│                               │   │   ├── TraitImpl.java
│                               │   │   ├── Traits.java
│                               │   │   └── Util.java
│                               │   └── function/
│                               │       ├── InBuiltLootFunctions.java
│                               │       ├── InBuiltPredicates.java
│                               │       ├── LootFunction.java
│                               │       └── Predicate.java
│                               ├── nbt/
│                               │   └── NBTUtils.java
│                               ├── number/
│                               │   ├── DoubleNumberProviders.java
│                               │   ├── IntNumberProviders.java
│                               │   └── NumberProvider.java
│                               ├── recipe/
│                               │   └── Recipe.java
│                               ├── tags/
│                               │   ├── ConditionsFor.java
│                               │   └── Tag.java
│                               ├── trims/
│                               │   ├── TrimMaterial.java
│                               │   └── TrimPattern.java
│                               └── worldgen/
│                                   ├── Biome.java
│                                   ├── BlockState.java
│                                   ├── Carver.java
│                                   ├── DensityFunction.java
│                                   ├── DensityFunctions.java
│                                   ├── FloatProvider.java
│                                   ├── HeightProvider.java
│                                   ├── LazyLoadedDensityFunction.java
│                                   ├── NoiseSettings.java
│                                   ├── Structure.java
│                                   ├── VerticalAnchor.java
│                                   ├── WorldgenContext.java
│                                   ├── WorldgenRegistries.java
│                                   ├── biome/
│                                   │   ├── BiomeSource.java
│                                   │   ├── BiomeSources.java
│                                   │   └── Climate.java
│                                   ├── math/
│                                   │   ├── CubicSpline.java
│                                   │   ├── NumberFunction.java
│                                   │   └── SplineInterpolator.java
│                                   ├── noise/
│                                   │   ├── BlendedNoise.java
│                                   │   ├── ImprovedNoise.java
│                                   │   ├── LazyLoadedNoise.java
│                                   │   ├── Noise.java
│                                   │   ├── NormalNoise.java
│                                   │   ├── PerlinNoise.java
│                                   │   └── SimplexNoise.java
│                                   ├── random/
│                                   │   ├── LegacyRandom.java
│                                   │   ├── MarsagliaPolarGaussian.java
│                                   │   ├── WorldgenRandom.java
│                                   │   ├── XoroshiroPositionalRandom.java
│                                   │   └── XoroshiroRandom.java
│                                   ├── storage/
│                                   │   ├── DoubleStorage.java
│                                   │   ├── DoubleStorageCache.java
│                                   │   ├── DoubleStorageCache2d.java
│                                   │   └── DoubleStorageThreadLocalImpl.java
│                                   └── util/
│                                       └── Util.java
├── datapack-tests/
│   ├── build.gradle.kts
│   └── src/
│       └── test/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── datapack/
│                               ├── loot/
│                               │   ├── LootTableTestData.java
│                               │   └── LootTableTests.java
│                               └── worldgen/
│                                   ├── DF.java
│                                   ├── DFVisualizer.java
│                                   ├── DensityFunctionTests.java
│                                   ├── NoiseTests.java
│                                   └── RandomTests.java
├── entities/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── entities/
│                               ├── FallingBlockEntity.java
│                               ├── MinestomEntitiesFeature.java
│                               └── PrimedTNTEntity.java
├── entity-meta/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── entitymeta/
│                               └── EntityTags.java
├── fluid-simulation/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── github/
│                       └── togar2/
│                           └── fluids/
│                               ├── EmptyFluid.java
│                               ├── FlowableFluid.java
│                               ├── Fluid.java
│                               ├── FluidPlacementRule.java
│                               ├── FluidSimulationFeature.java
│                               ├── MinestomFluids.java
│                               ├── WaterBlockBreakEvent.java
│                               └── WaterFluid.java
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── instance-meta/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── instancemeta/
│                               ├── InstanceMetaFeature.java
│                               └── tickets/
│                                   ├── TicketManager.java
│                                   └── TicketUtils.java
├── item-placeables/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── itemplaceables/
│                               └── ItemPlaceablesFeature.java
├── items/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── items/
│                               ├── FlintAndSteelHandler.java
│                               ├── ItemManager.java
│                               ├── ItemsFeature.java
│                               ├── VanillaItemHandler.java
│                               └── VanillaItems.java
├── jitpack.yml
├── loot-table/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── loot/
│                               ├── BlockExperience.java
│                               ├── LootContext.java
│                               ├── LootEntry.java
│                               ├── LootFeature.java
│                               ├── LootFunction.java
│                               ├── LootGenerator.java
│                               ├── LootNBT.java
│                               ├── LootNumber.java
│                               ├── LootPool.java
│                               ├── LootPredicate.java
│                               ├── LootScore.java
│                               ├── LootTable.java
│                               └── util/
│                                   ├── EnchantmentUtils.java
│                                   ├── ListOperation.java
│                                   ├── LootNumberRange.java
│                                   ├── RelevantEntity.java
│                                   ├── RelevantTarget.java
│                                   ├── nbt/
│                                   │   ├── NBTPath.java
│                                   │   ├── NBTReference.java
│                                   │   └── NBTUtils.java
│                                   └── predicate/
│                                       ├── DamageSourcePredicate.java
│                                       ├── EntityPredicate.java
│                                       ├── ItemPredicate.java
│                                       └── LocationPredicate.java
├── mojang-data/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── github/
│                       └── pesto/
│                           ├── MojangAssets.java
│                           └── MojangDataFeature.java
├── server/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── server/
│                               ├── VanillaDebug.java
│                               ├── VanillaEvents.java
│                               └── VanillaServer.java
├── settings.gradle.kts
├── survival/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── survival/
│                               └── Survival.java
└── world-generation/
    ├── build.gradle.kts
    └── src/
        └── main/
            └── java/
                └── net/
                    └── minestom/
                        └── vanilla/
                            └── generation/
                                ├── Aquifer.java
                                ├── NoiseChunk.java
                                ├── NoiseChunkGenerator.java
                                ├── RandomState.java
                                ├── SurfaceContext.java
                                ├── SurfaceSystem.java
                                ├── VanillaTestGenerator.java
                                ├── VanillaWorldGenerationFeature.java
                                └── VanillaWorldgen.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CONTRIBUTING.md
================================================
## How to contribute to Vanilla Reimplementation

#### **Did you find a bug?**

* Ensure that the associated system is implemented first. E.g. Don't report entities not spawning from spawners, if the
  spawner logic has not been implemented.

* Open a new GitHub issue if it's not already reported.

* Explain it clearly, with steps (or code) to reproduce it.

#### **Did you write some code that fixes a bug?**

* Open a new GitHub pull-request with the commits if it hasn't already been proposed.

* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.

#### **Do you intend to add a new feature or change an existing one?**

* Do not open a pull-request on GitHub until you have collected positive feedback about the change from a maintainer.
  You can do this in the [minestom discord](https://discord.gg/pkFRvqB).

#### **Do you have questions about the source code?**

* Ask any question about the code in the associated discord channel.

#### **Do you want to contribute to the Minestom documentation?**

* Feel free to do so! Just make sure to conform to the [standard-readme](https://github.com/RichardLitt/standard-readme)
  specification when editing the README.md.

## General Contribution Rules

* By contributing to the Vanilla Reimplementation project your code/contribution will be licensed under
  the [Apache Version 2.0](../LICENSE) license.

Minestom & VRI are community projects. We encourage you to contribute! :)

Thanks! :heart: :heart: :heart:

~Minestom Community


================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### Java template
# Compiled class file
*.class
*/build/*
build/*

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# IntelliJ and Gradle files
.idea/
out/
.gradle/

# Minestom
/minecraft_data/
/.minestom_tmp/

# Vanilla-like server
server.properties
world/
/datapack-tests/mojang-data
/mojang-data/1.20.4
/mojang-data/1.21.1


================================================
FILE: .gitmodules
================================================
[submodule "vanilla_worldgen_example"]
	path = vanilla_worldgen_example
	url = https://github.com/slicedlime/examples/
[submodule "prismarine-minecraft-data"]
    path = prismarine-minecraft-data
    url = https://github.com/PrismarineJS/minecraft-data
[submodule "Minestom"]
	path = Minestom
	url = https://github.com/Minestom/Minestom


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
# NOT READY FOR PRODUCTION

Priority is currently on the core of Minestom (see below). This project has only a very limited list of features.
Make sure to check out the project board [here](https://github.com/orgs/Minestom/projects/1).

# About Minestom

See [Minestom Project on GitHub](https://github.com/Minestom/Minestom)

# Cloning

`git clone --recurse-submodules https://github.com/Minestom/VanillaReimplementation`

# How to use

You can use this repo by finding the latest release [here](https://jitpack.io/#Minestom/VanillaReimplementation).
After selecting your release, make sure to choose which modules (vanila features) you want.
The "core" module is required. Everything else is optional and up to you.

Once you have added your modules to your classpath, you can initiate vri in your server's startup using this snippet:
`VanillaReimplementation vri = VanillaReimplementation.hook(MinecraftServer.process());`.

See [here](https://github.com/Minestom/VanillaReimplementation/blob/93f29ab67ffff7d78e34b12ab5f00619109c84c7/server/src/main/java/net/minestom/vanilla/server/VanillaServer.java#L44) for an example.

# How to contribute

See [the github project](https://github.com/orgs/Minestom/projects/1) for a list of relevant tasks that need to be done.


================================================
FILE: block-update-system/build.gradle.kts
================================================
dependencies {
    compileOnly(project(":core"))
}

================================================
FILE: block-update-system/src/main/java/net/minestom/vanilla/BlockUpdateFeature.java
================================================
package net.minestom.vanilla;


import net.kyori.adventure.key.Key;
import net.minestom.vanilla.blockupdatesystem.BlockUpdateManager;
import net.minestom.vanilla.logging.Loading;
import net.minestom.vanilla.randomticksystem.RandomTickManager;
import org.jetbrains.annotations.NotNull;

public class BlockUpdateFeature implements VanillaReimplementation.Feature {
    @Override
    public void hook(@NotNull HookContext context) {
        Loading.start("Block Update Manager");
        BlockUpdateManager.init(context);
        Loading.finish();

        Loading.start("Random Tick Manager");
        RandomTickManager.init(context);
        Loading.finish();
    }

    @Override
    public @NotNull Key key() {
        return Key.key("vri:blockupdate");
    }
}


================================================
FILE: block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdatable.java
================================================
package net.minestom.vanilla.blockupdatesystem;

import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;

public interface BlockUpdatable {
    /**
     * Called when a block is updated.
     *
     * @param info The block update info.
     */
    void blockUpdate(@NotNull Instance instance, @NotNull Point pos, @NotNull BlockUpdateInfo info);
}


================================================
FILE: block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdateInfo.java
================================================
package net.minestom.vanilla.blockupdatesystem;

public interface BlockUpdateInfo {

    static DestroyBlock DESTROY_BLOCK() {
        return new DestroyBlock();
    }

    static PlaceBlock PLACE_BLOCK() {
        return new PlaceBlock();
    }

    static ChunkLoad CHUNK_LOAD() {
        return new ChunkLoad();
    }

    static MoveBlock MOVE_BLOCK() {
        return new MoveBlock();
    }

    record DestroyBlock() implements BlockUpdateInfo {
    }

    record PlaceBlock() implements BlockUpdateInfo {
    }

    record ChunkLoad() implements BlockUpdateInfo {
    }

    record MoveBlock() implements BlockUpdateInfo {
    }
}


================================================
FILE: block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdateManager.java
================================================
package net.minestom.vanilla.blockupdatesystem;

import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventNode;
import net.minestom.server.event.instance.InstanceChunkLoadEvent;
import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.VanillaReimplementation;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * A utility class used to facilitate block updates
 */
public class BlockUpdateManager {
    // Block update manager by instance
    private static final Map<Instance, BlockUpdateManager> instance2BlockUpdateManager =
            Collections.synchronizedMap(new WeakHashMap<>());

    // Block updatables
    private static final Short2ObjectMap<BlockUpdatable> blockUpdatables = new Short2ObjectOpenHashMap<>();

    public static void registerUpdatable(short stateId, @NotNull BlockUpdatable updatable) {
        synchronized (blockUpdatables) {
            blockUpdatables.put(stateId, updatable);
        }
    }

    public static void init(@NotNull VanillaReimplementation.Feature.HookContext context) {
        EventNode<Event> eventNode = context.vri().process().eventHandler();

        eventNode.addListener(InstanceTickEvent.class, BlockUpdateManager::instanceTick);
        eventNode.addListener(PlayerBlockBreakEvent.class, event ->
                BlockUpdateManager.from(event.getPlayer().getInstance())
                        .scheduleNeighborsUpdate(event.getBlockPosition(),
                                BlockUpdateInfo.DESTROY_BLOCK())
        );
        eventNode.addListener(PlayerBlockPlaceEvent.class, event ->
                BlockUpdateManager.from(event.getPlayer().getInstance())
                        .scheduleNeighborsUpdate(event.getBlockPosition(),
                                BlockUpdateInfo.PLACE_BLOCK())
        );
        eventNode.addListener(InstanceChunkLoadEvent.class, event -> {
            Chunk chunk = event.getChunk();
            int minY = chunk.getMinSection() * Chunk.CHUNK_SECTION_SIZE;
            int maxY = chunk.getMaxSection() * Chunk.CHUNK_SECTION_SIZE;
            int minX = chunk.getChunkX() * Chunk.CHUNK_SIZE_X;
            int minZ = chunk.getChunkZ() * Chunk.CHUNK_SIZE_Z;

            Instance instance = event.getInstance();
            BlockUpdateManager.from(instance);

            synchronized (blockUpdatables) {
                for (int x = minX; x < minX + Chunk.CHUNK_SIZE_X; x++) {
                    for (int z = minZ; z < minZ + Chunk.CHUNK_SIZE_Z; z++) {
                        for (int y = minY; y < maxY; y++) {
                            Block block = chunk.getBlock(x, y, z);
                            BlockUpdatable updatable = blockUpdatables.get((short) block.stateId());
                            if (updatable == null) continue;
                            updatable.blockUpdate(instance, new Vec(x, y, z), BlockUpdateInfo.CHUNK_LOAD());
                        }
                    }
                }
            }
        });
    }

    private static void instanceTick(InstanceTickEvent event) {
        Instance instance = event.getInstance();
        from(instance).tick(event.getDuration());
    }

    public static @NotNull BlockUpdateManager from(@NotNull Instance instance) {
        return instance2BlockUpdateManager.computeIfAbsent(instance, BlockUpdateManager::new);
    }

    private final Map<Point, BlockUpdateInfo> updateNeighbors = Collections.synchronizedMap(new LinkedHashMap<>());
    private final BlockUpdateManager.UpdateHandler updateHandler;

    public BlockUpdateManager(@NotNull BlockUpdateManager.UpdateHandler updateHandler) {
        this.updateHandler = updateHandler;
    }

    private BlockUpdateManager(@NotNull Instance instance) {
        this.updateHandler = (pos, info) -> {
            if (instance.getBlock(pos).handler() instanceof BlockUpdatable updatable) {
                updatable.blockUpdate(instance, pos, info);
            }
        };
    }

    public interface UpdateHandler {
        void update(@NotNull Point pos, @NotNull BlockUpdateInfo info);
    }

    // Public api methods

    /**
     * Schedules this position's neighbors to be updated next tick.
     */
    public void scheduleNeighborsUpdate(Point pos, BlockUpdateInfo info) {
        updateNeighbors.put(pos, info);
    }

    // Public api methods end

    private void tick(int duration) {
        updateNeighbors(duration);
    }

    private void updateNeighbors(int duration) {
        if (updateNeighbors.isEmpty()) {
            return;
        }

        // Update all the neighbors
        for (Map.Entry<Point, BlockUpdateInfo> entry : updateNeighbors.entrySet()) {
            Point pos = entry.getKey();
            BlockUpdateInfo info = entry.getValue();

            int x = pos.blockX();
            int y = pos.blockY();
            int z = pos.blockZ();

            // For each surrounding block
            for (int offsetX = -1; offsetX < 2; offsetX++) {
                for (int offsetY = -1; offsetY < 2; offsetY++) {
                    for (int offsetZ = -1; offsetZ < 2; offsetZ++) {

                        // If block is not the original block
                        if (offsetX == 0 && offsetY == 0 && offsetZ == 0) {
                            continue;
                        }

                        // Get the block handler at the position
                        Point blockPos = new Pos(x + offsetX, y + offsetY, z + offsetZ);
                        updateHandler.update(blockPos, info);
                    }
                }
            }
        }

        updateNeighbors.clear();
    }
}


================================================
FILE: block-update-system/src/main/java/net/minestom/vanilla/randomticksystem/RandomTickManager.java
================================================
package net.minestom.vanilla.randomticksystem;

import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.VanillaReimplementation;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.Map;
import java.util.Random;
import java.util.WeakHashMap;

public class RandomTickManager {

    private static final @NotNull String RANDOM_TICK_SYSTEM_PROPERTY = "vri.gamerule.randomtickspeed";

    private static final Map<VanillaReimplementation, RandomTickManager> vri2managers =
            Collections.synchronizedMap(new WeakHashMap<>());
    private static final Short2ObjectMap<RandomTickable> randomTickables = new Short2ObjectOpenHashMap<>();

    private final VanillaReimplementation vri;
    private RandomTickManager(VanillaReimplementation vri) {
        this.vri = vri;
    }

    public static @NotNull RandomTickManager create(@NotNull VanillaReimplementation vri) {
        return vri2managers.computeIfAbsent(vri, RandomTickManager::new);
    }

    public static void init(VanillaReimplementation.Feature.@NotNull HookContext context) {
        RandomTickManager manager = create(context.vri());
        context.vri().process().eventHandler().addListener(InstanceTickEvent.class, event -> {
            int randomTickCount = Integer.parseInt(System.getProperty(RANDOM_TICK_SYSTEM_PROPERTY, "3"));
            manager.handleInstanceTick(event, randomTickCount);
        });
    }

    public static void registerRandomTickable(short stateId, RandomTickable randomTickable) {
        synchronized (randomTickables) {
            randomTickables.put(stateId, randomTickable);
        }
    }

    private void handleInstanceTick(InstanceTickEvent event, int randomTickCount) {
        Instance instance = event.getInstance();
        Random instanceRandom = vri.random(instance);
        synchronized (randomTickables) {
            for (Chunk chunk : instance.getChunks()) {
                int minSection = chunk.getMinSection();
                int maxSection = chunk.getMaxSection();
                for (int section = minSection; section < maxSection; section++) {
                    for (int i = 0; i < randomTickCount; i++) {
                        randomTickSection(instanceRandom, instance, chunk, section);
                    }
                }
            }
        }
    }

    private void randomTickSection(Random random, Instance instance, Chunk chunk, int minSection) {
        int minX = chunk.getChunkX() * Chunk.CHUNK_SIZE_X;
        int minZ = chunk.getChunkZ() * Chunk.CHUNK_SIZE_Z;
        int minY = minSection * Chunk.CHUNK_SECTION_SIZE;

        int x = minX + random.nextInt(Chunk.CHUNK_SIZE_X);
        int z = minZ + random.nextInt(Chunk.CHUNK_SIZE_Z);
        int y = minY + random.nextInt(Chunk.CHUNK_SECTION_SIZE);
        Point pos = new Vec(x, y, z);

        Block block = instance.getBlock(x, y, z);
        RandomTickable randomTickable = randomTickables.get((short) block.stateId());
        if (randomTickable == null) return;
        randomTickable.randomTick(new RandomTick(instance, pos, block));
    }

    private record RandomTick(Instance instance, Point position, Block block) implements RandomTickable.RandomTick {}
}


================================================
FILE: block-update-system/src/main/java/net/minestom/vanilla/randomticksystem/RandomTickable.java
================================================
package net.minestom.vanilla.randomticksystem;

import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;

public interface RandomTickable {

    void randomTick(@NotNull RandomTick randomTick);

    interface RandomTick {
        @NotNull Instance instance();
        @NotNull Point position();
        @NotNull Block block();
    }
}


================================================
FILE: blocks/build.gradle.kts
================================================
dependencies {
    compileOnly(project(":core"))
    compileOnly(project(":block-update-system"))
    compileOnly(project(":entity-meta"))
    compileOnly(project(":datapack-loading"))
}

================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks;

import net.kyori.adventure.key.Key;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

/**
 * Represents a singular vanilla block's logic. e.g. white bed, cake, furnace, etc.
 */
public abstract class VanillaBlockBehaviour implements BlockHandler {

    protected final @NotNull VanillaBlocks.BlockContext context;
    protected final short baseBlock;
    protected final @NotNull Key key;

    protected VanillaBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        this.context = context;
        this.baseBlock = context.stateId();
        this.key = Objects.requireNonNull(Block.fromStateId(context.stateId())).key();
    }

    /**
     * DO NOT USE THIS.
     * @see #onPlace(VanillaPlacement) instead.
     */
    @Override
    @Deprecated
    public void onPlace(@NotNull BlockHandler.Placement placement) {
    }

    public void onPlace(@NotNull VanillaPlacement placement) {
    }

    @Override
    public @NotNull Key getKey() {
        return key;
    }

    public interface VanillaPlacement {

        /**
         * @return the block that will be placed
         */
        @NotNull Block blockToPlace();

        /**
         * @return the instance that will be modified
         */
        @NotNull Instance instance();

        /**
         * @return the position of the block that will be placed
         */
        @NotNull Point position();

        /**
         * Overrides the current block to be placed.
         *
         * @param newBlock the new block to be placed
         */
        void blockToPlace(@NotNull Block newBlock);

        interface HasPlayer {
            @NotNull Player player();
        }
    }

}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlockLoot.java
================================================
package net.minestom.vanilla.blocks;

import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.vanilla.VanillaReimplementation;
import net.minestom.vanilla.datapack.Datapack;
import net.minestom.vanilla.datapack.loot.LootTable;
import net.minestom.vanilla.datapack.loot.context.LootContext;
import net.minestom.vanilla.datapack.loot.function.LootFunction;
import net.minestom.vanilla.datapack.loot.function.Predicate;
import net.minestom.vanilla.files.FileSystem;
import net.minestom.vanilla.logging.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.function.Consumer;
import java.util.random.RandomGenerator;

public record VanillaBlockLoot(VanillaReimplementation vri, Datapack datapack) {

    private record LootEntry(@Nullable List<LootFunction> functions, List<ItemStack> items, double weight) {
    }

    public void spawnLoot(@NotNull PlayerBlockBreakEvent event) {
        String blockName = event.getBlock().key().value();
        datapack.namespacedData().forEach((namespace, data) -> {
            FileSystem<LootTable> blocks = data.loot_tables().folder("blocks");
            var lootTable = blocks.file(blockName + ".json");
            if (lootTable == null) return;

            Block blockState = event.getBlock();
            Point origin = event.getBlockPosition();
            ItemStack tool = event.getPlayer().getItemInMainHand();
            Player entity = event.getPlayer();
            Block blockEntity = blockState.registry().blockEntity() == null ? null : blockState;
            Random random = vri.random(entity);

            LootContext context = new LootContext.Block(blockState, origin, tool, entity, blockEntity, null);

            List<ItemStack> items = new ArrayList<>();
            generateLootItems(lootTable, context, random, items::add);

            for (ItemStack item : items) {
                ItemEntity itemEntity = new ItemEntity(item);
                itemEntity.setInstance(entity.getInstance(), origin.add(0.5));
            }
        });
    }

    public List<ItemStack> getLoot(LootTable lootTable, LootContext context) {
        return getLoot(lootTable, context, vri.random(0));
    }

    public List<ItemStack> getLoot(LootTable lootTable, LootContext context, Random random) {
        List<ItemStack> items = new ArrayList<>();
        generateLootItems(lootTable, context, random, items::add);
        return items;
    }

    private void generateLootItems(LootTable lootTable, LootContext context, Random random, Consumer<ItemStack> out) {
        if (lootTable.pools() == null) return; // TODO: handle random_sequence
        for (LootTable.Pool pool : lootTable.pools()) {

            // Ensure all conditions are met
            if (fails(pool.conditions(), context)) continue;

            int rolls = pool.rolls().asInt().apply(() -> random);

            // collect all of the loot entries
            List<LootEntry> entries = new ArrayList<>();
            for (LootTable.Pool.Entry entry : pool.entries()) {

                // Ensure all conditions are met
                if (fails(entry.conditions(), context)) continue;

                // now we can add the entries
                addEntries(context, entry, itemGenerator -> {
                    double weight = itemGenerator.weight() == null ? 1 : Objects.requireNonNull(itemGenerator.weight()).asDouble().apply(() -> random);
                    var lootEntries = itemGenerator.apply(datapack, context);
                    for (List<ItemStack> lootEntryItems : lootEntries) {
                        entries.add(new LootEntry(itemGenerator.functions(), lootEntryItems, weight));
                    }
                });
            }

            // if there is no entries, we can skip this pool
            if (entries.isEmpty()) continue;

            // now that we have all the entries, we can roll for them
            double totalWeight = entries.stream().mapToDouble(LootEntry::weight).sum();
            for (int i = 0; i < rolls; i++) {
                LootEntry chosenLootEntry = null;
                double roll = random.nextDouble() * totalWeight;
                for (LootEntry lootEntry : entries) {
                    roll -= lootEntry.weight();
                    if (roll <= 0) {
                        chosenLootEntry = lootEntry;
                        break;
                    }
                }
                Objects.requireNonNull(chosenLootEntry);

                // we now have the loot entry, we need to apply the loot functions
                LootEntry finalChosenLootEntry = chosenLootEntry;
                chosenLootEntry.items()
                        .stream()
                        // loot entry functions
                        .map(item -> {
                            if (finalChosenLootEntry.functions() == null) return item;
                            for (LootFunction function : finalChosenLootEntry.functions()) {
                                item = function.apply(new LootFunctionContext(random, item, context));
                            }
                            return item;
                        })
                        // pool functions
                        .map(item -> {
                            if (pool.functions() == null) return item;
                            for (LootFunction function : pool.functions()) {
                                item = function.apply(new LootFunctionContext(random, item, context));
                            }
                            return item;
                        })
                        // table functions
                        .map(item -> {
                            if (lootTable.functions() == null) return item;
                            for (LootFunction function : lootTable.functions()) {
                                item = function.apply(new LootFunctionContext(random, item, context));
                            }
                            return item;
                        })
                        // add all of the items to the list
                        .forEach(out);
            }
        }
    }

    private record LootFunctionContext(RandomGenerator random, ItemStack itemStack, LootContext context) implements LootFunction.Context {
        @Override
        public <T> @Nullable T get(Trait<T> trait) {
            return context.get(trait);
        }
    }

    private static boolean fails(@Nullable List<Predicate> predicates, LootContext context) {
        if (predicates == null) return false;
        for (Predicate predicate : predicates) {
            if (!predicate.test(context)) {
                return true;
            }
        }
        return false;
    }

    private void addEntries(LootContext context, LootTable.Pool.Entry entry, Consumer<LootTable.Pool.Entry.ItemGenerator> out) {
        if (fails(entry.conditions(), context)) return;
        switch (entry.type().toString()) {
            case "minecraft:item", "minecraft:tag", "minecraft:dynamic", "minecraft:empty" -> out.accept((LootTable.Pool.Entry.ItemGenerator) entry);
            case "minecraft:loot_table" -> // TODO: recursive loot tables
                    Logger.debug("Recursive loot tables are not yet supported");
            case "minecraft:group" -> {
                LootTable.Pool.Entry.Group group = (LootTable.Pool.Entry.Group) entry;
                for (LootTable.Pool.Entry groupEntry : group.children()) {
                    addEntries(context, groupEntry, out);
                }
            }
            case "minecraft:alternatives" -> {
                LootTable.Pool.Entry.Alternatives alternatives = (LootTable.Pool.Entry.Alternatives) entry;
                for (LootTable.Pool.Entry alternative : alternatives.children()) {
                    if (fails(alternative.conditions(), context)) continue;
                    addEntries(context, alternative, out);
                    break;
                }
            }
            case "minecraft:sequence" -> {
                LootTable.Pool.Entry.Sequence sequence = (LootTable.Pool.Entry.Sequence) entry;
                for (LootTable.Pool.Entry alternative : sequence.children()) {
                    if (fails(alternative.conditions(), context)) break;
                    addEntries(context, alternative, out);
                }
            }
        }
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlocks.java
================================================
package net.minestom.vanilla.blocks;

import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.EventNode;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.VanillaReimplementation;
import net.minestom.vanilla.blocks.behaviours.*;
import net.minestom.vanilla.blocks.behaviours.oxidisable.OxidatableBlockBehaviour;
import net.minestom.vanilla.blocks.behaviours.oxidisable.WaxedBlockBehaviour;
import net.minestom.vanilla.blocks.behaviours.recipe.*;
import net.minestom.vanilla.blockupdatesystem.BlockUpdatable;
import net.minestom.vanilla.blockupdatesystem.BlockUpdateManager;
import net.minestom.vanilla.datapack.DatapackLoadingFeature;
import net.minestom.vanilla.randomticksystem.RandomTickManager;
import net.minestom.vanilla.randomticksystem.RandomTickable;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

/**
 * All blocks available in the vanilla reimplementation
 */
public enum VanillaBlocks {

    SAND(Block.SAND, GravityBlockBehaviour::new),
    RED_SAND(Block.RED_SAND, GravityBlockBehaviour::new),
    GRAVEL(Block.GRAVEL, GravityBlockBehaviour::new),

    // Start of concrete powders
    WHITE_CONCRETE_POWDER(Block.WHITE_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.WHITE_CONCRETE)),
    BLACK_CONCRETE_POWDER(Block.BLACK_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.BLACK_CONCRETE)),
    LIGHT_BLUE_CONCRETE_POWDER(Block.LIGHT_BLUE_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.LIGHT_BLUE_CONCRETE)),
    BLUE_CONCRETE_POWDER(Block.BLUE_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.BLUE_CONCRETE)),
    RED_CONCRETE_POWDER(Block.RED_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.RED_CONCRETE)),
    GREEN_CONCRETE_POWDER(Block.GREEN_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.GREEN_CONCRETE)),
    YELLOW_CONCRETE_POWDER(Block.YELLOW_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.YELLOW_CONCRETE)),
    PURPLE_CONCRETE_POWDER(Block.PURPLE_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.PURPLE_CONCRETE)),
    MAGENTA_CONCRETE_POWDER(Block.MAGENTA_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.MAGENTA_CONCRETE)),
    CYAN_CONCRETE_POWDER(Block.CYAN_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.CYAN_CONCRETE)),
    PINK_CONCRETE_POWDER(Block.PINK_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.PINK_CONCRETE)),
    GRAY_CONCRETE_POWDER(Block.GRAY_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.GRAY_CONCRETE)),
    LIGHT_GRAY_CONCRETE_POWDER(Block.LIGHT_GRAY_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.LIGHT_GRAY_CONCRETE)),
    ORANGE_CONCRETE_POWDER(Block.ORANGE_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.ORANGE_CONCRETE)),
    BROWN_CONCRETE_POWDER(Block.BROWN_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.BROWN_CONCRETE)),
    LIME_CONCRETE_POWDER(Block.LIME_CONCRETE_POWDER, (context) -> new ConcretePowderBlockBehaviour(context, Block.LIME_CONCRETE)),
    // End of concrete powders

    // Start of oxidisable copper
    // Blocks
    COPPER_BLOCK(Block.COPPER_BLOCK, (context) ->           new OxidatableBlockBehaviour(context, Block.COPPER_BLOCK, Block.EXPOSED_COPPER, Block.WAXED_COPPER_BLOCK, 0)),
    EXPOSED_COPPER(Block.EXPOSED_COPPER, (context) ->       new OxidatableBlockBehaviour(context, Block.COPPER_BLOCK, Block.WEATHERED_COPPER, Block.WAXED_EXPOSED_COPPER, 1)),
    WEATHERED_COPPER(Block.WEATHERED_COPPER, (context) ->   new OxidatableBlockBehaviour(context, Block.EXPOSED_COPPER, Block.OXIDIZED_COPPER, Block.WAXED_WEATHERED_COPPER, 2)),
    OXIDIZED_COPPER(Block.OXIDIZED_COPPER, (context) ->     new OxidatableBlockBehaviour(context, Block.WEATHERED_COPPER, Block.OXIDIZED_COPPER, Block.WAXED_OXIDIZED_COPPER, 3)),
    // Cut Blocks
    CUT_COPPER(Block.CUT_COPPER, (context) ->                     new OxidatableBlockBehaviour(context, Block.CUT_COPPER, Block.EXPOSED_CUT_COPPER, Block.WAXED_CUT_COPPER, 0)),
    EXPOSED_CUT_COPPER(Block.EXPOSED_CUT_COPPER, (context) ->     new OxidatableBlockBehaviour(context, Block.CUT_COPPER, Block.WEATHERED_CUT_COPPER, Block.WAXED_EXPOSED_CUT_COPPER, 1)),
    WEATHERED_CUT_COPPER(Block.WEATHERED_CUT_COPPER, (context) -> new OxidatableBlockBehaviour(context, Block.EXPOSED_CUT_COPPER, Block.OXIDIZED_CUT_COPPER, Block.WAXED_WEATHERED_CUT_COPPER, 2)),
    OXIDIZED_CUT_COPPER(Block.OXIDIZED_CUT_COPPER, (context) ->   new OxidatableBlockBehaviour(context, Block.WEATHERED_CUT_COPPER, Block.OXIDIZED_CUT_COPPER, Block.WAXED_OXIDIZED_CUT_COPPER, 3)),
    // Stairs
    CUT_COPPER_STAIRS(Block.CUT_COPPER_STAIRS, (context) ->                     new OxidatableBlockBehaviour(context, Block.CUT_COPPER_STAIRS, Block.EXPOSED_CUT_COPPER_STAIRS, Block.WAXED_CUT_COPPER_STAIRS, 0)),
    EXPOSED_CUT_COPPER_STAIRS(Block.EXPOSED_CUT_COPPER_STAIRS, (context) ->     new OxidatableBlockBehaviour(context, Block.CUT_COPPER_STAIRS, Block.WEATHERED_CUT_COPPER_STAIRS, Block.WAXED_EXPOSED_CUT_COPPER_STAIRS, 1)),
    WEATHERED_CUT_COPPER_STAIRS(Block.WEATHERED_CUT_COPPER_STAIRS, (context) -> new OxidatableBlockBehaviour(context, Block.EXPOSED_CUT_COPPER_STAIRS, Block.OXIDIZED_CUT_COPPER_STAIRS, Block.WAXED_WEATHERED_CUT_COPPER_STAIRS, 2)),
    OXIDIZED_CUT_COPPER_STAIRS(Block.OXIDIZED_CUT_COPPER_STAIRS, (context) ->   new OxidatableBlockBehaviour(context, Block.WEATHERED_CUT_COPPER_STAIRS, Block.OXIDIZED_CUT_COPPER_STAIRS, Block.WAXED_OXIDIZED_CUT_COPPER_STAIRS, 3)),
    // Slabs
    CUT_COPPER_SLAB(Block.CUT_COPPER_SLAB, (context) ->                     new OxidatableBlockBehaviour(context, Block.CUT_COPPER_SLAB, Block.EXPOSED_CUT_COPPER_SLAB, Block.WAXED_CUT_COPPER_SLAB, 0)),
    EXPOSED_CUT_COPPER_SLAB(Block.EXPOSED_CUT_COPPER_SLAB, (context) ->     new OxidatableBlockBehaviour(context, Block.CUT_COPPER_SLAB, Block.WEATHERED_CUT_COPPER_SLAB, Block.WAXED_EXPOSED_CUT_COPPER_SLAB, 1)),
    WEATHERED_CUT_COPPER_SLAB(Block.WEATHERED_CUT_COPPER_SLAB, (context) -> new OxidatableBlockBehaviour(context, Block.EXPOSED_CUT_COPPER_SLAB, Block.OXIDIZED_CUT_COPPER_SLAB, Block.WAXED_WEATHERED_CUT_COPPER_SLAB, 2)),
    OXIDIZED_CUT_COPPER_SLAB(Block.OXIDIZED_CUT_COPPER_SLAB, (context) ->   new OxidatableBlockBehaviour(context, Block.WEATHERED_CUT_COPPER_SLAB, Block.OXIDIZED_CUT_COPPER_SLAB, Block.WAXED_OXIDIZED_CUT_COPPER_SLAB, 3)),
    // End of copper

    // Start of waxed copper
    // Blocks
    WAXED_COPPER_BLOCK(Block.WAXED_COPPER_BLOCK, (context) ->         new WaxedBlockBehaviour(context, Block.COPPER_BLOCK, 0)),
    WAXED_EXPOSED_COPPER(Block.WAXED_EXPOSED_COPPER, (context) ->     new WaxedBlockBehaviour(context, Block.EXPOSED_COPPER, 1)),
    WAXED_WEATHERED_COPPER(Block.WAXED_WEATHERED_COPPER, (context) -> new WaxedBlockBehaviour(context, Block.WEATHERED_COPPER, 2)),
    WAXED_OXIDIZED_COPPER(Block.WAXED_OXIDIZED_COPPER, (context) ->   new WaxedBlockBehaviour(context, Block.OXIDIZED_COPPER, 3)),
    // Cut Blocks
    WAXED_CUT_COPPER(Block.WAXED_CUT_COPPER, (context) ->                     new WaxedBlockBehaviour(context, Block.CUT_COPPER, 0)),
    WAXED_EXPOSED_CUT_COPPER(Block.WAXED_EXPOSED_CUT_COPPER, (context) ->     new WaxedBlockBehaviour(context, Block.EXPOSED_CUT_COPPER, 1)),
    WAXED_WEATHERED_CUT_COPPER(Block.WAXED_WEATHERED_CUT_COPPER, (context) -> new WaxedBlockBehaviour(context, Block.WEATHERED_CUT_COPPER, 2)),
    WAXED_OXIDIZED_CUT_COPPER(Block.WAXED_OXIDIZED_CUT_COPPER, (context) ->   new WaxedBlockBehaviour(context, Block.OXIDIZED_CUT_COPPER, 3)),
    // Stairs
    WAXED_CUT_COPPER_STAIRS(Block.WAXED_CUT_COPPER_STAIRS, (context) ->                     new WaxedBlockBehaviour(context, Block.CUT_COPPER_STAIRS, 0)),
    WAXED_EXPOSED_CUT_COPPER_STAIRS(Block.WAXED_EXPOSED_CUT_COPPER_STAIRS, (context) ->     new WaxedBlockBehaviour(context, Block.EXPOSED_CUT_COPPER_STAIRS, 1)),
    WAXED_WEATHERED_CUT_COPPER_STAIRS(Block.WAXED_WEATHERED_CUT_COPPER_STAIRS, (context) -> new WaxedBlockBehaviour(context, Block.WEATHERED_CUT_COPPER_STAIRS, 2)),
    WAXED_OXIDIZED_CUT_COPPER_STAIRS(Block.WAXED_OXIDIZED_CUT_COPPER_STAIRS, (context) ->   new WaxedBlockBehaviour(context, Block.OXIDIZED_CUT_COPPER_STAIRS, 3)),
    // Slabs
    WAXED_CUT_COPPER_SLAB(Block.WAXED_CUT_COPPER_SLAB, (context) ->                     new WaxedBlockBehaviour(context, Block.CUT_COPPER_SLAB, 0)),
    WAXED_EXPOSED_CUT_COPPER_SLAB(Block.WAXED_EXPOSED_CUT_COPPER_SLAB, (context) ->     new WaxedBlockBehaviour(context, Block.EXPOSED_CUT_COPPER_SLAB, 1)),
    WAXED_WEATHERED_CUT_COPPER_SLAB(Block.WAXED_WEATHERED_CUT_COPPER_SLAB, (context) -> new WaxedBlockBehaviour(context, Block.WEATHERED_CUT_COPPER_SLAB, 2)),
    WAXED_OXIDIZED_CUT_COPPER_SLAB(Block.WAXED_OXIDIZED_CUT_COPPER_SLAB, (context) ->   new WaxedBlockBehaviour(context, Block.OXIDIZED_CUT_COPPER_SLAB, 3)),
    // End of waxed copper

    // Start of beds
    WHITE_BED(Block.WHITE_BED, BedBlockBehaviour::new),
    BLACK_BED(Block.BLACK_BED, BedBlockBehaviour::new),
    LIGHT_BLUE_BED(Block.LIGHT_BLUE_BED, BedBlockBehaviour::new),
    BLUE_BED(Block.BLUE_BED, BedBlockBehaviour::new),
    RED_BED(Block.RED_BED, BedBlockBehaviour::new),
    GREEN_BED(Block.GREEN_BED, BedBlockBehaviour::new),
    YELLOW_BED(Block.YELLOW_BED, BedBlockBehaviour::new),
    PURPLE_BED(Block.PURPLE_BED, BedBlockBehaviour::new),
    MAGENTA_BED(Block.MAGENTA_BED, BedBlockBehaviour::new),
    CYAN_BED(Block.CYAN_BED, BedBlockBehaviour::new),
    PINK_BED(Block.PINK_BED, BedBlockBehaviour::new),
    GRAY_BED(Block.GRAY_BED, BedBlockBehaviour::new),
    LIGHT_GRAY_BED(Block.LIGHT_GRAY_BED, BedBlockBehaviour::new),
    ORANGE_BED(Block.ORANGE_BED, BedBlockBehaviour::new),
    BROWN_BED(Block.BROWN_BED, BedBlockBehaviour::new),
    LIME_BED(Block.LIME_BED, BedBlockBehaviour::new),
    // End of beds

    FIRE(Block.FIRE, FireBlockBehaviour::new),
    NETHER_PORTAL(Block.NETHER_PORTAL, NetherPortalBlockBehaviour::new),
    END_PORTAL(Block.END_PORTAL, EndPortalBlockBehaviour::new),

    TNT(Block.TNT, TNTBlockBehaviour::new),

    CHEST(Block.CHEST, ChestBlockBehaviour::new),
    TRAPPED_CHEST(Block.TRAPPED_CHEST, TrappedChestBlockBehaviour::new),
    ENDER_CHEST(Block.ENDER_CHEST, EnderChestBlockBehaviour::new),
    JUKEBOX(Block.JUKEBOX, JukeboxBlockBehaviour::new),

    // recipes
    CRAFTING_TABLE(Block.CRAFTING_TABLE, CraftingTableBehaviour::new),
    FURNACE(Block.FURNACE, FurnaceBehaviour::new),
    SMOKER(Block.SMOKER, SmokerBehaviour::new),
    BLAST_FURNACE(Block.BLAST_FURNACE, BlastingFurnaceBehaviour::new),

    STONE_CUTTER(Block.STONECUTTER, StonecutterBehaviour::new),
    CAMPFIRE(Block.CAMPFIRE, CampfireBehaviour::new),
    SOUL_CAMPFIRE(Block.SOUL_CAMPFIRE, CampfireBehaviour::new),
    SMITHING_TABLE(Block.SMITHING_TABLE, SmithingTableBehaviour::new),

    // Start of cakes
    CAKE(Block.CAKE, CakeBlockBehaviour::new),
    CANDLE_CAKE(Block.CANDLE_CAKE, CakeBlockBehaviour::new),
    WHITE_CANDLE_CAKE(Block.WHITE_CANDLE_CAKE, CakeBlockBehaviour::new),
    ORANGE_CANDLE_CAKE(Block.ORANGE_CANDLE_CAKE, CakeBlockBehaviour::new),
    MAGENTA_CANDLE_CAKE(Block.MAGENTA_CANDLE_CAKE, CakeBlockBehaviour::new),
    LIGHT_BLUE_CANDLE_CAKE(Block.LIGHT_BLUE_CANDLE_CAKE, CakeBlockBehaviour::new),
    YELLOW_CANDLE_CAKE(Block.YELLOW_CANDLE_CAKE, CakeBlockBehaviour::new),
    LIME_CANDLE_CAKE(Block.LIME_CANDLE_CAKE, CakeBlockBehaviour::new),
    PINK_CANDLE_CAKE(Block.PINK_CANDLE_CAKE, CakeBlockBehaviour::new),
    GRAY_CANDLE_CAKE(Block.GRAY_CANDLE_CAKE, CakeBlockBehaviour::new),
    LIGHT_GRAY_CANDLE_CAKE(Block.LIGHT_GRAY_CANDLE_CAKE, CakeBlockBehaviour::new),
    CYAN_CANDLE_CAKE(Block.CYAN_CANDLE_CAKE, CakeBlockBehaviour::new),
    PURPLE_CANDLE_CAKE(Block.PURPLE_CANDLE_CAKE, CakeBlockBehaviour::new),
    BLUE_CANDLE_CAKE(Block.BLUE_CANDLE_CAKE, CakeBlockBehaviour::new),
    BROWN_CANDLE_CAKE(Block.BROWN_CANDLE_CAKE, CakeBlockBehaviour::new),
    GREEN_CANDLE_CAKE(Block.GREEN_CANDLE_CAKE, CakeBlockBehaviour::new),
    BLACK_CANDLE_CAKE(Block.BLACK_CANDLE_CAKE, CakeBlockBehaviour::new)
    // End of cakes

    ;
    private final short stateId;
    private final @NotNull Context2Handler context2handler;

    VanillaBlocks(@NotNull Block minestomBlock, @NotNull Context2Handler context2handler) {
        this.stateId = (short) minestomBlock.stateId();
        this.context2handler = context -> {
            if (context.stateId() != minestomBlock.stateId()) {
                throw new IllegalStateException("Block registry mismatch. Registered block: " + minestomBlock.stateId() +
                        " !=  Given block:" + context.stateId());
            }
            return context2handler.apply(context);
        };
    }

    interface Context2Handler {
        @NotNull VanillaBlockBehaviour apply(@NotNull BlockContext context);
    }

    /**
     * Used to provide context for creating block handlers
     */
    public interface BlockContext {
        short stateId();

        @NotNull VanillaReimplementation vri();
    }

    /**
     * Creates a block handler from the context
     *
     * @param context the context
     * @return the block handler
     */
    public @NotNull VanillaBlockBehaviour create(@NotNull BlockContext context) {
        return context2handler.apply(context);
    }

    /**
     * Register all vanilla blocks. ConnectionManager will handle replacing the basic
     * block with its custom variant.
     *
     * @param vri the vanilla reimplementation object
     */
    public static void registerAll(@NotNull VanillaReimplementation vri) {

        EventNode<Event> events = EventNode.all("vanilla-blocks");

        // block loot
        VanillaBlockLoot loot = new VanillaBlockLoot(vri, vri.feature(DatapackLoadingFeature.class).current());
        events.addListener(EventListener.builder(PlayerBlockBreakEvent.class)
                .filter(event -> !event.isCancelled())
                .filter(event -> event.getPlayer().getGameMode() != GameMode.CREATIVE)
                .handler(loot::spawnLoot)
                .build());

        Short2ObjectMap<VanillaBlockBehaviour> stateId2behaviour = new Short2ObjectOpenHashMap<>();

        for (VanillaBlocks vb : values()) {
            BlockContext context = new BlockContext() {
                @Override
                public short stateId() {
                    return vb.stateId;
                }

                @Override
                public @NotNull VanillaReimplementation vri() {
                    return vri;
                }
            };
            VanillaBlockBehaviour behaviour = vb.context2handler.apply(context);

            for (Block possibleState : Objects.requireNonNull(Block.fromStateId(vb.stateId)).possibleStates()) {
                short possibleStateId = (short) possibleState.stateId();
                stateId2behaviour.put(possibleStateId, behaviour);
            }

            if (behaviour instanceof BlockUpdatable updatable)
                BlockUpdateManager.registerUpdatable(vb.stateId, updatable);

            if (behaviour instanceof RandomTickable randomTickable)
                RandomTickManager.registerRandomTickable(vb.stateId, randomTickable);
        }

        registerEvents(events, stateId2behaviour);

        vri.process().eventHandler().addChild(events);
    }

    private static void registerEvents(EventNode<Event> node, Short2ObjectMap<VanillaBlockBehaviour> behaviours) {
        node.addListener(EventListener.builder(PlayerBlockPlaceEvent.class)
                .filter(event -> behaviours.containsKey((short) event.getBlock().stateId()))
                .handler(event -> {
                    short stateId = (short) event.getBlock().stateId();
                    Block block = Objects.requireNonNull(Block.fromStateId(stateId));
                    var behaviour = behaviours.get(stateId);

                    behaviour.onPlace(new PlayerPlacement(event));
                    Block blockToPlace = event.getBlock();
                    if (blockToPlace.compare(block)) {
                        event.setBlock(blockToPlace.withHandler(behaviour));
                    }
                })
                .build());
    }

    private record PlayerPlacement(PlayerBlockPlaceEvent event) implements VanillaBlockBehaviour.VanillaPlacement,
            VanillaBlockBehaviour.VanillaPlacement.HasPlayer {

        @Override
        public @NotNull Block blockToPlace() {
            return event.getBlock();
        }

        @Override
        public @NotNull Instance instance() {
            return event.getInstance();
        }

        @Override
        public @NotNull Point position() {
            return event.getBlockPosition();
        }

        @Override
        public void blockToPlace(@NotNull Block newBlock) {
            event.setBlock(newBlock);
        }

        @Override
        public @NotNull Player player() {
            return event.getPlayer();
        }
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlocksFeature.java
================================================
package net.minestom.vanilla.blocks;

import net.kyori.adventure.key.Key;
import net.minestom.server.coordinate.Point;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.BlockUpdateFeature;
import net.minestom.vanilla.VanillaReimplementation;
import net.minestom.vanilla.datapack.DatapackLoadingFeature;
import org.jetbrains.annotations.NotNull;

import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

public class VanillaBlocksFeature implements VanillaReimplementation.Feature {

    @Override
    public void hook(@NotNull HookContext context) {
        VanillaReimplementation vri = context.vri();
        VanillaBlocks.registerAll(vri);

        vri.process().eventHandler().addListener(PlayerBlockPlaceEvent.class, event -> {
            Block block = event.getBlock();
            Instance instance = event.getInstance();
            Point position = event.getBlockPosition();
            AtomicReference<Block> blockToPlace = new AtomicReference<>(block);

            if (block.handler() instanceof VanillaBlockBehaviour vanillaHandler) {
                // Create the new placement object
                VanillaBlockBehaviour.VanillaPlacement placement = new PlacementImpl(blockToPlace, instance, position);
                vanillaHandler.onPlace(placement);
            }

            event.setBlock(blockToPlace.get());
        });
    }

    private record PlacementImpl(AtomicReference<Block> blockToPlaceRef, Instance instance, Point position) implements VanillaBlockBehaviour.VanillaPlacement {
        @Override
        public @NotNull Block blockToPlace() {
            return blockToPlaceRef.get();
        }

        @Override
        public @NotNull Instance instance() {
            return instance;
        }

        @Override
        public @NotNull Point position() {
            return position;
        }

        @Override
        public void blockToPlace(@NotNull Block newBlock) {
            blockToPlaceRef.getAndSet(newBlock);
            // TODO: Run vanillaHandler.onPlace again on the new block if it's a vanilla block
        }
    }

    @Override
    public @NotNull Key key() {
        return Key.key("vri:blocks");
    }

    @Override
    public @NotNull Set<Class<? extends VanillaReimplementation.Feature>> dependencies() {
        return Set.of(BlockUpdateFeature.class, DatapackLoadingFeature.class);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/BedBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.EntityPose;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.Direction;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.world.DimensionType;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.instance.VanillaExplosion;
import org.jetbrains.annotations.NotNull;

@SuppressWarnings("UnstableApiUsage")
public class BedBlockBehaviour extends VanillaBlockBehaviour {
    public BedBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

//    @Override
//    protected BlockPropertyList createPropertyValues() {
//        return new BlockPropertyList().facingProperty("facing").booleanProperty("occupied").property("part", "foot", "head");
//    }


    @Override
    public void onPlace(@NotNull VanillaPlacement placement) {
        if (!(placement instanceof VanillaPlacement.HasPlayer hasPlayer)) {
            return;
        }

        Instance instance = placement.instance();
        Point pos = placement.position();
        Player player = hasPlayer.player();

        ItemStack itemStack = player.getItemInMainHand(); // TODO: Hand determination

        Block bedBlock = itemStack.material().block();

        // TODO: Proper block placement management
        Direction playerDirection = MathUtils.getHorizontalDirection(player.getPosition().yaw());

        Point bedHeadPosition = pos.add(playerDirection.normalX(), playerDirection.normalY(), playerDirection.normalZ());
        Block blockAtPotentialBedHead = instance.getBlock(bedHeadPosition);

        if (isReplaceable(blockAtPotentialBedHead)) {
            Block foot = placeBed(instance, bedBlock, bedHeadPosition, playerDirection);
            placement.blockToPlace(foot);
        } else {
            placement.blockToPlace(placement.instance().getBlock(placement.position()));
        }

    }

    private boolean isReplaceable(Block blockAtPosition) {
        return blockAtPosition.isAir() || blockAtPosition.isLiquid();
    }

    private Block placeBed(Instance instance, Block bedBlock, Point headPosition, Direction facing) {
        Block correctFacing = bedBlock.withProperty("facing", facing.name().toLowerCase());

        Block footBlock = correctFacing.withProperty("part", "foot");
        Block headBlock = correctFacing.withProperty("part", "head").withHandler(new BedBlockBehaviour(this.context));
        instance.setBlock(headPosition, headBlock);
        return footBlock;
    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        Instance instance = interaction.getInstance();
        Point pos = interaction.getBlockPosition();
        Player player = interaction.getPlayer();
        var dimensionKey = instance.getDimensionType();
        DimensionType dimension = MinecraftServer.getDimensionTypeRegistry().get(dimensionKey);

        if (dimension.bedWorks()) {
            // TODO: make player sleep
            // TODO: checks for mobs
            // TODO: check for day

            // If time is not day
//            long dayTime = instance.getTime() % 24000L;
//            if (!(dayTime > 12541L && dayTime < 23458L)) {
//                return true;
//            }

            // Make player sleep
            PlayerMeta meta = player.getPlayerMeta();
            meta.setBedInWhichSleepingPosition(pos);
            meta.setPose(EntityPose.SLEEPING);

            // Schedule player getting out of bed
            MinecraftServer.getSchedulerManager().buildTask(() -> {
                        if (!player.getPlayerConnection().isOnline()) {
                            return;
                        }

                        meta.setBedInWhichSleepingPosition(null);
                        meta.setPose(EntityPose.STANDING);
                    })
                    .delay(101, TimeUnit.SERVER_TICK)
                    .schedule();
            return true;
        }

        VanillaExplosion.builder(pos.add(0.5), 5)
                .isFlaming(true)
                .build()
                .apply(instance);
        return true;
    }

    @Override
    public void onDestroy(@NotNull Destroy destroy) {
        Instance instance = destroy.getInstance();
        Block block = destroy.getBlock();
        Point pos = destroy.getBlockPosition();

        boolean isHead = "head".equals(block.getProperty("part"));
        Direction facing = Direction.valueOf(block.getProperty("facing").toUpperCase());

        if (isHead) {
            facing = facing.opposite();
        }

        Point otherPartPosition = pos.add(facing.normalX(), facing.normalY(), facing.normalZ());
        instance.setBlock(pos, Block.AIR);
        instance.setBlock(otherPartPosition, Block.AIR);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/CakeBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

import java.util.Map;

import static java.util.Map.entry;

public class CakeBlockBehaviour extends VanillaBlockBehaviour {

    private static final Map<Block, Material> candleCakes = Map.ofEntries(
            entry(Block.CANDLE_CAKE, Material.CANDLE),
            entry(Block.WHITE_CANDLE_CAKE, Material.WHITE_CANDLE),
            entry(Block.ORANGE_CANDLE_CAKE, Material.ORANGE_CANDLE),
            entry(Block.MAGENTA_CANDLE_CAKE, Material.MAGENTA_CANDLE),
            entry(Block.LIGHT_BLUE_CANDLE_CAKE, Material.LIGHT_BLUE_CANDLE),
            entry(Block.YELLOW_CANDLE_CAKE, Material.YELLOW_CANDLE),
            entry(Block.LIME_CANDLE_CAKE, Material.LIME_CANDLE),
            entry(Block.PINK_CANDLE_CAKE, Material.PINK_CANDLE),
            entry(Block.GRAY_CANDLE_CAKE, Material.GRAY_CANDLE),
            entry(Block.LIGHT_GRAY_CANDLE_CAKE, Material.LIGHT_GRAY_CANDLE),
            entry(Block.CYAN_CANDLE_CAKE, Material.CYAN_CANDLE),
            entry(Block.PURPLE_CANDLE_CAKE, Material.PURPLE_CANDLE),
            entry(Block.BLUE_CANDLE_CAKE, Material.BLUE_CANDLE),
            entry(Block.BROWN_CANDLE_CAKE, Material.BROWN_CANDLE),
            entry(Block.GREEN_CANDLE_CAKE, Material.GREEN_CANDLE),
            entry(Block.BLACK_CANDLE_CAKE, Material.BLACK_CANDLE)
    );

    private static final ItemStack flint_and_steel = ItemStack.of(Material.FLINT_AND_STEEL);

    public CakeBlockBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context);
    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        Player player = interaction.getPlayer();
        Block block = interaction.getBlock();
        Point point = interaction.getBlockPosition();
        Instance instance = interaction.getInstance();

        int food = player.getFood();
        float saturation = player.getFoodSaturation();
        ItemStack item = player.getItemInMainHand();

        // Player is trying to light candle cake
        if (item.isSimilar(flint_and_steel) && candleCakes.containsKey(block) &&
                !Boolean.parseBoolean(block.getProperty("lit"))) {
            instance.setBlock(point, block.withProperty("lit", "true"));

            // TODO: Handle tool durability
            return true;
        }

        // Player is eating cake
        if (food < 20) {
            tryDropCandle(block, instance, point);

            // Update hunger values
            int newFood = Math.max(20, food + 2);
            float newSaturation = Math.max(20f, saturation + 0.4f);
            player.setFood(newFood);
            player.setFoodSaturation(newSaturation);
        }
        return true;
    }

    @Override
    public void onDestroy(@NotNull Destroy destroy) {
        Block block = destroy.getBlock();
        Instance instance = destroy.getInstance();
        Point point = destroy.getBlockPosition();

        tryDropCandle(block, instance, point);
    }

    private void tryDropCandle(Block block, Instance instance, Point point) {
        if (block != Block.CAKE) {
            instance.setBlock(point, Block.CAKE.withProperty("bites", "1"));
            ItemStack candle = ItemStack.of(candleCakes.get(block));
            new ItemEntity(candle).setInstance(instance);
        }
    }
}

================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/ChestBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

public class ChestBlockBehaviour extends InventoryBlockBehaviour {
    public ChestBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context, InventoryType.CHEST_3_ROW, Component.text("Chest"));
    }

    @Override
    public boolean dropContentsOnDestroy() {
        return true;
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/ConcretePowderBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

// TODO: When placing concrete powder in water, it turns to the solid block correctly, however it falls like a regular concrete powder block
public class ConcretePowderBlockBehaviour extends GravityBlockBehaviour {
    private final Block solidifiedBlock;

    public ConcretePowderBlockBehaviour(@NotNull VanillaBlocks.BlockContext context, Block solidifiedBlock) {
        super(context);
        this.solidifiedBlock = solidifiedBlock;
    }

    @Override
    public void onPlace(@NotNull VanillaBlockBehaviour.VanillaPlacement placement) {
        super.onPlace(placement);
        tryConvert(placement.instance(), placement.position());
    }

    @Override
    public void tick(@NotNull Tick tick) {
        tryConvert(tick.getInstance(), tick.getBlockPosition());
    }

    private void tryConvert(Instance instance, Point blockPosition) {

        int x = blockPosition.blockX();
        int y = blockPosition.blockY();
        int z = blockPosition.blockZ();

        // TODO: support block tags

        if (
                instance.getBlock(x, y + 1, z).compare(Block.WATER) || // above
                        instance.getBlock(x - 1, y, z).compare(Block.WATER) || // west
                        instance.getBlock(x + 1, y, z).compare(Block.WATER) || // east
                        instance.getBlock(x, y, z - 1).compare(Block.WATER) || // north
                        instance.getBlock(x, y, z + 1).compare(Block.WATER)    // south
        ) {
            instance.setBlock(blockPosition, solidifiedBlock);
        }
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/EndPortalBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.world.DimensionType;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.dimensions.VanillaDimensionTypes;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

public class EndPortalBlockBehaviour extends VanillaBlockBehaviour {
    public EndPortalBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

//    @Override
//    protected BlockPropertyList createPropertyValues() {
//        return new BlockPropertyList();
//    }

    @Override
    public void onTouch(@NotNull Touch touch) {
        Instance instance = touch.getInstance();
        Entity touching = touch.getTouching();
        var key = instance.getDimensionType();
        DimensionType dimension = MinecraftServer.getDimensionTypeRegistry().get(key);

        DimensionType targetDimension = VanillaDimensionTypes.OVERWORLD;
        Optional<Instance> potentialTargetInstance = MinecraftServer.getInstanceManager().getInstances().stream()
                .filter(in -> {
                    var key1 = in.getDimensionType();
                    return MinecraftServer.getDimensionTypeRegistry().get(key1) == targetDimension;
                })
                .findFirst();

        // TODO: event
        if (potentialTargetInstance.isPresent()) {
            Instance targetInstance = potentialTargetInstance.get();
            Pos spawnPoint;
            final int obsidianPlatformX = 100;
            final int obsidianPlatformY = 48;
            final int obsidianPlatformZ = 0;

            if (targetDimension == VanillaDimensionTypes.OVERWORLD) { // teleport to spawn point
                if (touching instanceof Player) {
                    spawnPoint = ((Player) touching).getRespawnPoint();
                } else { // TODO: world spawnpoint
                    spawnPoint = new Pos(0, 80, 0);
                }
            } else {
                // teleport to the obsidian platform, and recreate it if necessary
                int yLevel = touching instanceof Player ? 49 : 50;
                spawnPoint = new Pos(obsidianPlatformX, yLevel, obsidianPlatformZ);
            }

            if (targetDimension.effects().equals("the_end")) {
                for (int x = -1; x <= 1; x++) {
                    for (int z = -1; z <= 1; z++) {
                        targetInstance.loadChunk(obsidianPlatformX / 16 + x, obsidianPlatformZ / 16 + z);
                    }
                }

                // clear 5x3x5 area around platform
                for (int x = 0; x < 5; x++) {
                    for (int z = 0; z < 5; z++) {
                        for (int y = 0; y < 3; y++) {
                            targetInstance.setBlock(obsidianPlatformX + x, obsidianPlatformY + y + 1, obsidianPlatformZ + z, Block.AIR);
                        }
                    }
                }
            }
            touching.setInstance(targetInstance);
            touching.teleport(spawnPoint);
        }
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/EnderChestBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.system.EnderChestSystem;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class EnderChestBlockBehaviour extends InventoryBlockBehaviour {
    public EnderChestBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context, InventoryType.CHEST_3_ROW, Component.text("Ender Chest"));
    }

    @Override
    public boolean dropContentsOnDestroy() {
        return false;
    }

    @Override
    protected List<ItemStack> getAllItems(Instance instance, Point pos, Player player) {
        return EnderChestSystem.getInstance().getItems(player);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/FireBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.system.NetherPortal;
import org.jetbrains.annotations.NotNull;

public class FireBlockBehaviour extends VanillaBlockBehaviour {
    public FireBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

//    @Override
//    protected BlockPropertyList createPropertyValues() {
//        return new BlockPropertyList().intRange("age", 0, 15);
//    }

    @Override
    public void onTouch(@NotNull Touch touch) {
        Entity touching = touch.getTouching();

        if (!(touching instanceof LivingEntity livingEntity)) {
            return;
        }

        if (livingEntity.isOnFire()) {
            return;
        }

        livingEntity.damage(DamageType.IN_FIRE, 1.0f);
        livingEntity.setFireTicks(8 * 20);
    }

    public void checkForPortal(Instance instance, Point pos, Block block) {
        NetherPortal portal = NetherPortal.findPortalFrameFromFrameBlock(instance, pos);

        if (portal == null) {
            return;
        }

        if (portal.tryFillFrame(instance)) {
            portal.register(instance);
        }
    }

    @Override
    public void onPlace(@NotNull VanillaPlacement placement) {
        // check for Nether portal immediately
        checkForPortal(placement.instance(), placement.position(), placement.blockToPlace());
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/GravityBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.VanillaRegistry;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blockupdatesystem.BlockUpdatable;
import net.minestom.vanilla.blockupdatesystem.BlockUpdateInfo;
import net.minestom.vanilla.blockupdatesystem.BlockUpdateManager;
import net.minestom.vanilla.entitymeta.EntityTags;
import org.jetbrains.annotations.NotNull;

public class GravityBlockBehaviour extends VanillaBlockBehaviour implements BlockUpdatable {
    public GravityBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

    @Override
    public void onPlace(@NotNull VanillaPlacement placement) {
        Instance instance = placement.instance();
        Point position = placement.position();
        Block block = placement.blockToPlace();

        if (checkFall(instance, position, block)) {
            placement.blockToPlace(Block.AIR);
        }
    }

    /**
     * Checks if a block should fall
     *
     * @param instance the instance the block is in
     * @param position the position of the block
     * @return true if the block should fall
     */
    public boolean checkFall(Instance instance, Point position, Block block) {
        Block below = instance.getBlock(position.blockX(), position.blockY() - 1, position.blockZ());

        // Exit out now if block below is solid
        if (below.isSolid()) {
            return false;
        }

        // Schedule block update
        BlockUpdateManager.from(instance).scheduleNeighborsUpdate(position, BlockUpdateInfo.MOVE_BLOCK());

        // Create the context
        Pos initialPosition = new Pos(position.x() + 0.5f, Math.round(position.y()), position.z() + 0.5f);
        VanillaRegistry.EntityContext entityContext = context.vri().entityContext(EntityType.FALLING_BLOCK,
                initialPosition, nbt -> nbt.setTag(EntityTags.FallingBlock.BLOCK, block));
        Entity entity = context.vri().createEntityOrDummy(entityContext);

        // Spawn the entity
        entity.setInstance(instance, initialPosition);
        return true;
    }

    @Override
    public void blockUpdate(@NotNull Instance instance, @NotNull Point pos, @NotNull BlockUpdateInfo info) {
        checkFall(instance, pos, instance.getBlock(pos));
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/InventoryBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.Direction;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blocks.behaviours.chestlike.BlockInventory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnknownNullability;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * Base class for blocks with an inventory.
 * <p>
 * This class needs onPlace to be able to change the block being placed
 */
public abstract class InventoryBlockBehaviour extends VanillaBlockBehaviour {

    public static final Tag<List<ItemStack>> TAG_ITEMS = Tag.ItemStack("vri:chest_items").list();
    protected static final Random rng = new Random();
    protected final InventoryType type;
    protected final Component title;

    public InventoryBlockBehaviour(@NotNull VanillaBlocks.BlockContext context, InventoryType type, Component title) {
        super(context);
        this.type = type;
        this.title = title;
    }

    @Override
    public void onPlace(@NotNull VanillaPlacement placement) {
        Block block = placement.blockToPlace();
        Instance instance = placement.instance();
        Point pos = placement.position();

        @UnknownNullability List<ItemStack> items = block.getTag(TAG_ITEMS);

        if (items != null) {
            return;
        }

        ItemStack[] itemsArray = new ItemStack[type.getSize()];
        Arrays.fill(itemsArray, ItemStack.AIR);

        // Override the block to set
        Block blockToSet = block.withTag(TAG_ITEMS, List.of(itemsArray));
        placement.blockToPlace(blockToSet);
    }

    @Override
    public void onDestroy(@NotNull Destroy destroy) {
        Instance instance = destroy.getInstance();
        Point pos = destroy.getBlockPosition();
        Block block = destroy.getBlock();

        // TODO: Introduce a way to get the block this is getting replaced with, enabling us to remove the tick delay.
        destroy.getInstance().scheduleNextTick(ignored -> {
            if (instance.getBlock(pos).compare(block)) {
                // Same block, don't remove chest inventory
                return;
            }

            // Different block, remove chest inventory
            List<ItemStack> items = BlockInventory.remove(instance, pos);

            if (!dropContentsOnDestroy()) {
                return;
            }

            for (ItemStack item : items) {

                if (item == null) {
                    continue;
                }

                ItemEntity entity = new ItemEntity(item);

                entity.setInstance(destroy.getInstance());
                entity.teleport(new Pos(pos.x() + rng.nextDouble(), pos.y() + .5f, pos.z() + rng.nextDouble()));
            }
        });
    }

//    @Override
//    public short getVisualBlockForPlacement(Player player, Player.Hand hand, BlockPosition position) {
//        // TODO: handle double chests
//        boolean waterlogged = Block.fromStateId(player.getInstance().getBlockStateId(position.getX(), position.getY(), position.getZ())) == Block.WATER;
//        float yaw = player.getPosition().getYaw();
//        Direction direction = MathUtils.getHorizontalDirection(yaw).opposite();
//        return getBaseBlockState().with("facing", direction.name().toLowerCase()).with("waterlogged", String.valueOf(waterlogged)).getBlockId();
//    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        // TODO: handle double chests
        // TODO: Handle crouching players

        Block block = interaction.getBlock();
        Instance instance = interaction.getInstance();
        Point pos = interaction.getBlockPosition();
        Player player = interaction.getPlayer();

        Block above = instance.getBlock(pos.blockX(), pos.blockY() + 1, pos.blockZ());

        if (above.isSolid()) { // FIXME: chests below transparent blocks cannot be opened
            return false;
        }

        Inventory chestInventory = BlockInventory.from(instance, pos, type, title);
        player.openInventory(chestInventory);
        return true;
    }

    public abstract boolean dropContentsOnDestroy();

    /**
     * Gets the items in this block only
     *
     * @param block the block
     * @return the items
     */
    protected @NotNull List<ItemStack> getItems(Block block) {
        List<ItemStack> items = block.getTag(TAG_ITEMS);
        if (items == null) {
            throw new IllegalStateException("Chest block has no items");
        }
        if (items.size() != this.type.getSize()) {
            throw new IllegalStateException("Invalid items size");
        }
        return items;
    }

    /**
     * Sets the items in this block only
     *
     * @param block the block
     * @param items the items
     */
    protected Block setItems(Block block, List<ItemStack> items) {
        if (items.size() != this.type.getSize()) {
            throw new IllegalStateException("Invalid items size");
        }
        return block.withTag(TAG_ITEMS, items);
    }

    /**
     * Gets all items represented by this position in this instance
     *
     * @param instance the instance
     * @param pos      the position
     * @return all items in the position in the instance
     */
    protected List<ItemStack> getAllItems(Instance instance, Point pos, Player player) {
        Block block = instance.getBlock(pos);
        List<ItemStack> items = new ArrayList<>(getItems(block));

        Point positionOfOtherChest = pos;
        Direction facing = Direction.valueOf(block.getProperty("facing").toUpperCase());
        String type = block.getProperty("type");

        switch (type) {
            case "single" -> {
                return List.copyOf(items);
            }
            case "left" -> positionOfOtherChest = positionOfOtherChest.add(-facing.normalZ(), 0, facing.normalX());
            case "right" -> positionOfOtherChest = positionOfOtherChest.add(facing.normalZ(), 0, -facing.normalX());
            default -> throw new IllegalArgumentException("Invalid chest type: " + type);
        }

        Block otherBlock = instance.getBlock(positionOfOtherChest);
        BlockHandler handler = otherBlock.handler();

        if (handler instanceof InventoryBlockBehaviour chestLike) {
            items.addAll(chestLike.getItems(otherBlock));
        }

        return List.copyOf(items);
    }

//    @Override
//    public Data readBlockEntity(NBTCompound nbt, Instance instance, BlockPosition position, Data originalData) {
//        ChestBlockEntity data;
//        if (originalData instanceof ChestBlockEntity) {
//            data = (ChestBlockEntity) originalData;
//        } else {
//            data = new ChestBlockEntity(position.copy());
//        }
//
//        // TODO: CustomName
//        // TODO: Lock
//        // TODO: LootTable
//        // TODO: LootTableSeed
//
//        if (nbt.containsKey("Items")) {
//            NBTUtils.loadAllItems(nbt.getList("Items"), data.getInventory());
//        }
//
//        return data;
//    }

//    @Override
//    public void writeBlockEntity(BlockPosition position, Data blockData, NBTCompound nbt) {
//        // TODO: CustomName
//        // TODO: Lock
//        // TODO: LootTable
//        // TODO: LootTableSeed
//        if (blockData instanceof ChestBlockEntity) {
//            ChestBlockEntity data = (ChestBlockEntity) blockData;
//            NBTList<NBTCompound> list = new NBTList<>(NBTTypes.TAG_Compound);
//            NBTUtils.saveAllItems(list, data.getInventory());
//            nbt.set("Items", list);
//        }
//    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/JukeboxBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.MinecraftServer;
import net.minestom.server.component.DataComponents;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerHand;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.jukebox.JukeboxSong;
import net.minestom.server.item.ItemStack;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.tag.Tag;
import net.minestom.server.worldevent.WorldEvent;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.inventory.InventoryManipulation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;
import java.util.Random;

/**
 * Reimplementation of the jukebox block
 * <p>
 * Requires onPlace enhancements
 */
public class JukeboxBlockBehaviour extends VanillaBlockBehaviour {

    public static final Tag<ItemStack> DISC_KEY = Tag.ItemStack("minestom:jukebox_disc");

    public JukeboxBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

    @Override
    public void onDestroy(@NotNull Destroy destroy) {
        if (!(destroy instanceof PlayerDestroy)) return;
        stopPlayback(destroy.getInstance(), destroy.getBlockPosition(), destroy.getBlock());
    }

    public @Nullable ItemStack getDisc(Block block) {
        return block.getTag(DISC_KEY);
    }

    public @NotNull Block withDisc(Block block, @NotNull ItemStack disc) {
        if (isNotMusicDisc(disc)) {
            throw new IllegalArgumentException("disc passed to JukeboxBlockHandle#withDisc was not a music disc.");
        }
        return block.withTag(DISC_KEY, disc);
    }

    private boolean isNotMusicDisc(ItemStack itemStack) {
        return !itemStack.has(DataComponents.JUKEBOX_PLAYABLE);
    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        Player player = interaction.getPlayer();
        PlayerHand hand = interaction.getHand();
        Instance instance = interaction.getInstance();
        Block block = interaction.getBlock();
        Point pos = interaction.getBlockPosition();
        ItemStack heldItem = player.getItemInMainHand();

        ItemStack stack = this.getDisc(block);

        if (stack != null && !stack.isAir()) {
            stopPlayback(instance, pos, block);
            block = block.withTag(DISC_KEY, ItemStack.AIR);
            instance.setBlock(pos, block.withProperty("has_record", "false"));
            return true;
        }

        if (isNotMusicDisc(heldItem)) {
            return true;
        }

        instance.setBlock(pos, withDisc(block, heldItem).withProperty("has_record", "true"));

        InventoryManipulation.consumeItemIfNotCreative(player, heldItem, hand);

        JukeboxSong song = heldItem.get(DataComponents.JUKEBOX_PLAYABLE).holder().resolve(MinecraftServer.getJukeboxSongRegistry());
        DynamicRegistry.Key<JukeboxSong> songKey = MinecraftServer.getJukeboxSongRegistry().getKey(song);
        int songId = MinecraftServer.getJukeboxSongRegistry().getId(songKey);

        // TODO: Group packet?
        instance.getPlayers()
                .stream()
                .filter(player1 -> player1.getDistance(pos) < 64)
                .forEach(player1 ->
                        player1.playEffect(
                                WorldEvent.SOUND_PLAY_JUKEBOX_SONG,
                                pos.blockX(),
                                pos.blockY(),
                                pos.blockZ(),
                                songId,
                                false
                        )
                );

        return true;
    }

    @Override
    public boolean isTickable() {
        return true;
    }

    public void tick(@NotNull Tick tick) {
        Instance instance = tick.getInstance();

        long age = instance.getWorldAge();

        // Continue only every 3 seconds
        if (age % (MinecraftServer.TICK_PER_SECOND * 3L) != 0) {
        }

        // TODO: Play sound to all players without the sound playing
    }

//    @Override
//    public Data readBlockEntity(NBTCompound nbt, Instance instance, BlockPosition position, Data originalData) {
//        JukeboxBlockEntity data;
//        if (originalData instanceof JukeboxBlockEntity) {
//            data = (JukeboxBlockEntity) originalData;
//        } else {
//            data = new JukeboxBlockEntity(position.copy());
//        }
//
//        if(nbt.containsKey("RecordItem")) {
//            data.setDisc(ItemStack.fromNBT(nbt.getCompound("RecordItem")));
//        }
//        return super.readBlockEntity(nbt, instance, position, originalData);
//    }
//
//    @Override
//    public void writeBlockEntity(BlockPosition position, Data blockData, NBTCompound nbt) {
//        if(blockData instanceof JukeboxBlockEntity) {
//            JukeboxBlockEntity data = (JukeboxBlockEntity) blockData;
//            nbt.set("RecordItem", data.getDisc().toNBT());
//        }
//    }

    /**
     * Stops playback in an instance
     */
    private void stopPlayback(Instance instance, Point pos, Block block) {
        ItemEntity discEntity = new ItemEntity(Objects.requireNonNull(getDisc(block)));
        discEntity.setInstance(instance);
        discEntity.teleport(new Pos(pos.x() + 0.5f, pos.y() + 1f, pos.z() + 0.5f));
        discEntity.setPickable(true);

        Random rng = new Random();
        final float horizontalSpeed = 2f;
        final float verticalSpeed = 5f;

        discEntity.setVelocity(new Vec(
                rng.nextGaussian() * horizontalSpeed,
                rng.nextFloat() * verticalSpeed,
                rng.nextGaussian() * horizontalSpeed
        ));

        discEntity.setInstance(instance);

        // TODO: Group Packet?
        instance.getPlayers().forEach(playerInInstance -> {
            // stop playback
            playerInInstance.playEffect(
                    WorldEvent.SOUND_STOP_JUKEBOX_SONG,
                    pos.blockX(),
                    pos.blockY(),
                    pos.blockZ(),
                    -1,
                    false
            );
        });
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/NetherPortalBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.event.Event;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.tag.Tag;
import net.minestom.server.world.DimensionType;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blockupdatesystem.BlockUpdatable;
import net.minestom.vanilla.blockupdatesystem.BlockUpdateInfo;
import net.minestom.vanilla.dimensions.VanillaDimensionTypes;
import net.minestom.vanilla.system.NetherPortal;
import net.minestom.vanilla.system.nether.EntityEnterNetherPortalEvent;
import net.minestom.vanilla.system.nether.NetherPortalTeleportEvent;
import net.minestom.vanilla.system.nether.NetherPortalUpdateEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

public class NetherPortalBlockBehaviour extends VanillaBlockBehaviour implements BlockUpdatable {

    /**
     * Time the entity has spent inside a portal. Reset when entering a different portal or by
     * reentering a portal after leaving one
     */
    public static final Tag<Long> TICKS_SPENT_IN_PORTAL_KEY = Tag.Long("minestom:time_spent_in_nether_portal").defaultValue(0L);

    /**
     * Prevents multiple updates from different portal blocks
     */
    public static final Tag<Long> LAST_PORTAL_UPDATE_KEY = Tag.Long("minestom:last_nether_portal_update_time").defaultValue(Long.MAX_VALUE);

    /**
     * Used to check whether the last portal entered is corresponding to this portal block or not
     */
    public static final Tag<Long> LAST_PORTAL_KEY = Tag.Long("minestom:last_nether_portal");

    /**
     * Time before teleporting an entity
     */
    public static final Tag<Long> PORTAL_COOLDOWN_TIME_KEY = Tag.Long("minestom:nether_portal_cooldown_time").defaultValue(0L);

    /**
     * The portal related to this block
     */
    public static final Tag<Long> RELATED_PORTAL_KEY = Tag.Long("minestom:related_portal");

    public NetherPortalBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

    @Override
    public void onTouch(@NotNull Touch touch) {
        Block block = touch.getBlock();
        Instance instance = touch.getInstance();
        Point pos = touch.getBlockPosition();
        Entity touching = touch.getTouching();

        Long lastPortalUpdate = block.getTag(LAST_PORTAL_UPDATE_KEY);

        if (lastPortalUpdate == null) {
            return;
        }

        if (lastPortalUpdate < touching.getAliveTicks() - 2) { // if a tick happened with no portal update, that means the entity left the portal at some point
            Block newBlock = block
                    .withTag(LAST_PORTAL_UPDATE_KEY, 0L)
                    .withTag(TICKS_SPENT_IN_PORTAL_KEY, 0L);

            instance.setBlock(pos, newBlock);
            return;
        }

        if (lastPortalUpdate == touching.getAliveTicks()) {
            return;
        }

        NetherPortal portal = getPortal(block);
        long ticksSpentInPortal = updateTimeInPortal(instance, pos, touching, block, portal);

        Long portalCooldownTime = block.getTag(PORTAL_COOLDOWN_TIME_KEY);

        if (portalCooldownTime == null) {
            portalCooldownTime = 0L;
        }

        if (ticksSpentInPortal >= portalCooldownTime) {
            attemptTeleport(instance, touching, block, ticksSpentInPortal, portal);
        }
    }

    private long updateTimeInPortal(Instance instance, Point position, Entity touching, Block block, NetherPortal portal) {
        Block newBlock = block;

        newBlock = newBlock.withTag(LAST_PORTAL_UPDATE_KEY, touching.getAliveTicks());
        Long ticksSpentInPortal = block.getTag(TICKS_SPENT_IN_PORTAL_KEY);

        if (ticksSpentInPortal == null) {
            ticksSpentInPortal = 0L;
        }

        NetherPortal portalEntityWasIn = NetherPortal.fromId(newBlock.getTag(LAST_PORTAL_KEY));

        if (portal != portalEntityWasIn) {
            ticksSpentInPortal = 0L; // reset counter
        }

        newBlock = newBlock.withTag(LAST_PORTAL_KEY, portal.id()); // data.set(, portal, NetherPortal.class);

        if (ticksSpentInPortal == 0) {
            Event event = new EntityEnterNetherPortalEvent(touching, position, portal);

            MinecraftServer.getGlobalEventHandler().call(event);
        }

        ticksSpentInPortal++;

        newBlock = newBlock.withTag(TICKS_SPENT_IN_PORTAL_KEY, ticksSpentInPortal);

        instance.setBlock(position, newBlock);

        Event event = new NetherPortalUpdateEvent(touching, position, portal, instance, ticksSpentInPortal);

        MinecraftServer.getGlobalEventHandler().call(event);
        return ticksSpentInPortal;
    }

    private void attemptTeleport(Instance instance, Entity touching, Block block, long ticksSpentInPortal, NetherPortal portal) {
        DimensionType targetDimension;
        Point position = touching.getPosition();

        double targetX = position.x() / 8;
        double targetY = position.y();
        double targetZ = position.z() / 8;

        var key = instance.getDimensionType();
        DimensionType dimension = MinecraftServer.getDimensionTypeRegistry().get(key);
        if (dimension.effects().equals("nether")) {
            targetDimension = MinecraftServer.getDimensionTypeRegistry().get(DimensionType.OVERWORLD);
            targetX = position.x() * 8;
            targetZ = position.z() * 8;
        } else {
            targetDimension = VanillaDimensionTypes.OVERWORLD;
        }

        // TODO: event to change portal linking
        final DimensionType finalTargetDimension = targetDimension;
        Optional<Instance> potentialTargetInstance = MinecraftServer.getInstanceManager().getInstances().stream()
                .filter(in -> {
                    var key1 = in.getDimensionType();
                    return MinecraftServer.getDimensionTypeRegistry().get(key1) == targetDimension;
                })
                .findFirst();

        if (potentialTargetInstance.isEmpty()) {
            return;
        }

        Instance targetInstance = potentialTargetInstance.get();
        Pos targetPosition = new Pos(targetX, targetY, targetZ);
        NetherPortal targetPortal = getCorrespondingNetherPortal(targetInstance, targetPosition);

        boolean generatePortal = false;
        if (targetPortal == null) { // no existing portal, will create one

            NetherPortal.Axis axis = portal.getAxis();
            Pos bottomRight = new Pos(
                    targetX - axis.xMultiplier,
                    targetY - 1,
                    targetZ - axis.zMultiplier
            );

            Pos topLeft = new Pos(
                    targetX + 2 * axis.xMultiplier,
                    targetY + 3,
                    targetZ + 2 * axis.zMultiplier
            );

            targetPortal = new NetherPortal(portal.getAxis(), bottomRight, topLeft);
            generatePortal = true;
        }

        targetPosition = calculateTargetPosition(touching, portal, targetPortal);

        NetherPortalTeleportEvent event = new NetherPortalTeleportEvent(touching, position, portal, ticksSpentInPortal, targetInstance, targetPosition, targetPortal, generatePortal);
        MinecraftServer.getGlobalEventHandler().call(event);

        if (!event.isCancelled()) {
            Block newBlock = block
                    .withTag(LAST_PORTAL_UPDATE_KEY, 0L)
                    .withTag(LAST_PORTAL_KEY, portal.id())
                    .withTag(TICKS_SPENT_IN_PORTAL_KEY, 0L);
            instance.setBlock(position, newBlock);
            teleport(instance, touching, event);
        }
    }

    private @Nullable NetherPortal getCorrespondingNetherPortal(Instance targetInstance, Point targetPosition) {
        Block block = targetInstance.getBlock(targetPosition);
        return NetherPortal.fromId(block.getTag(RELATED_PORTAL_KEY));
    }

    private Pos calculateTargetPosition(Entity touching, NetherPortal portal, NetherPortal targetPortal) {
        Point targetCenter = targetPortal.getCenter();

        if (portal == null) { // if this block is not isolated
            return new Pos(
                    targetCenter.x() + 0.5,
                    targetCenter.y(),
                    targetCenter.z() + 0.5
            );
        }

        Pos touchingPos = touching.getPosition();
        double touchingX = touchingPos.x();
        double touchingY = touchingPos.y();
        double touchingZ = touchingPos.z();

        Vec portalCenter = portal.getCenter();
        double portalCenterX = portalCenter.x();
        double portalCenterY = portalCenter.y();
        double portalCenterZ = portalCenter.z();

        NetherPortal.Axis portalAxis = portal.getAxis();
        double portalAxisXMultiplier = portalAxis.xMultiplier;
        double portalAxisZMultiplier = portalAxis.zMultiplier;

        NetherPortal.Axis targetAxis = targetPortal.getAxis();
        double targetAxisXMultiplier = targetAxis.xMultiplier;
        double targetAxisZMultiplier = targetAxis.zMultiplier;

        double relativeX = (touchingX - portalCenterX) / (portal.computeWidth() * portalAxisXMultiplier + portalAxisZMultiplier);
        double relativeY = (touchingY - portalCenterY) / portal.computeHeight();
        double relativeZ = (touchingZ - portalCenterZ) / (portal.computeWidth() * portalAxisZMultiplier + portalAxisXMultiplier);

        double targetMultiplierX = (targetPortal.computeWidth() * targetAxisXMultiplier + targetAxisZMultiplier);
        double targetMultiplierY = targetPortal.computeHeight();
        double targetMultiplierZ = (targetPortal.computeWidth() * targetAxisZMultiplier + targetAxisXMultiplier);

        return new Pos(
                targetCenter.x() + relativeX * targetMultiplierX,
                targetCenter.y() + relativeY * targetMultiplierY,
                targetCenter.z() + relativeZ * targetMultiplierZ
        );
    }

    private void teleport(Instance instance, Entity touching, NetherPortalTeleportEvent event) {
        Instance targetInstance = event.getTargetInstance();
        if (event.createsNewPortal()) {
            event.getTargetPortal().generate(targetInstance);
        }

        if (targetInstance != instance) {
            touching.setInstance(targetInstance);
        }

        Pos targetTeleportationPosition = new Pos(event.getTargetPosition());

        touching.teleport(targetTeleportationPosition).thenRun(() -> {
            Vec velocity = touching.getVelocity();

            if (
                    event.getPortal() != null &&
                            event.getPortal().getAxis()
                                    != event.getTargetPortal().getAxis()
            ) {
                double swapTmp = velocity.x();

                touching.setVelocity(new Vec(
                        swapTmp,
                        velocity.z(),
                        swapTmp
                ));
            }
        });
    }

    @Override
    public void onDestroy(@NotNull Destroy destroy) {
        Block block = destroy.getBlock();
        Instance instance = destroy.getInstance();

        NetherPortal netherPortal = getPortal(block);
        if (netherPortal != null) {
            netherPortal.breakFrame(instance);
            netherPortal.unregister(instance);
        }
    }

    private NetherPortal getPortal(Block block) {
        return NetherPortal.fromId(block.getTag(RELATED_PORTAL_KEY));
    }

//    @Override
//    public void updateFromNeighbor(Instance instance, Point thisPosition, Point neighborPosition, boolean directNeighbor) {
//
//    }

    private void breakPortalIfNoLongerValid(Instance instance, Point blockPosition) {
        NetherPortal netherPortal = getPortal(instance.getBlock(blockPosition));

        if (netherPortal == null) {
            return;
        }

        if (netherPortal.isStillValid(instance)) {
            return;
        }

        netherPortal.breakFrame(instance);
    }

    public void setRelatedPortal(Instance instance, Point blockPosition, Block block, NetherPortal portal) {
        instance.setBlock(blockPosition, block.withTag(RELATED_PORTAL_KEY, portal.id()));
    }

    @Override
    public void blockUpdate(@NotNull Instance instance, @NotNull Point pos, @NotNull BlockUpdateInfo info) {
        breakPortalIfNoLongerValid(instance, pos);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/TNTBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerHand;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
import net.minestom.vanilla.VanillaRegistry;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.entitymeta.EntityTags;
import org.jetbrains.annotations.NotNull;

import java.util.Random;

public class TNTBlockBehaviour extends VanillaBlockBehaviour {

    public static final Random TNT_RANDOM = new Random();

    public TNTBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context);
    }

//    @Override
//    protected BlockPropertyList createPropertyValues() {
//        return new BlockPropertyList().booleanProperty("unstable");
//    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        Point blockPosition = interaction.getBlockPosition();
        Player player = interaction.getPlayer();
        PlayerHand hand = interaction.getHand();

        if (player.getItemInHand(hand).material() != Material.FLINT_AND_STEEL) {
            return true;
        }

        player.getInstance().setBlock(blockPosition, Block.AIR);
        spawnPrimedTNT(player.getInstance(), blockPosition, 80);

        return true;
    }

    private void spawnPrimedTNT(Instance instance, Point blockPosition, int fuseTime) {
        Pos initialPosition = new Pos(blockPosition.blockX() + 0.5f, blockPosition.blockY() + 0f, blockPosition.blockZ() + 0.5f);

        // Create the entity
        VanillaRegistry.EntityContext entityContext = context.vri().entityContext(EntityType.TNT, initialPosition,
                writable -> writable.setTag(EntityTags.PrimedTnt.FUSE_TIME, fuseTime));
        Entity primedTnt = context.vri().createEntityOrDummy(entityContext);

        // Spawn it with random velocity
        primedTnt.setInstance(instance, initialPosition);
        primedTnt.setVelocity(new Vec(TNT_RANDOM.nextFloat() * 2f - 1f, TNT_RANDOM.nextFloat() * 5f, TNT_RANDOM.nextFloat() * 2f - 1f));
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/TrappedChestBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours;

import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

public class TrappedChestBlockBehaviour extends InventoryBlockBehaviour {
    // TODO: redstone signal

    public TrappedChestBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
        super(context, InventoryType.CHEST_3_ROW, Component.text("Trapped Chest"));
    }

//    @Override
//    protected BlockPropertyList createPropertyValues() {
//        return super.createPropertyValues().property("type", "single", "left", "right");
//    }

    @Override
    public boolean dropContentsOnDestroy() {
        return true;
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/BlockInventory.java
================================================
package net.minestom.vanilla.blocks.behaviours.chestlike;

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point;
import net.minestom.server.instance.Instance;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.vanilla.blocks.behaviours.InventoryBlockBehaviour;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class BlockInventory extends Inventory {
    private static final Map<Point, BlockInventory> BLOCK_INVENTORY_MAP = new ConcurrentHashMap<>();

    protected final Instance instance;
    protected final Point pos;

    private BlockInventory(Instance instance, Point pos, InventoryType inventoryType, Component title) {
        super(inventoryType, title);

        this.instance = instance;
        this.pos = pos;

        // Set items
        List<ItemStack> itemsList = instance.getBlock(pos).getTag(InventoryBlockBehaviour.TAG_ITEMS);
        if (itemsList != null) {
            for (int i = 0; i < itemsList.size(); i++) {
                this.itemStacks[i] = itemsList.get(i);
            }
        }
    }

    public static BlockInventory from(Instance instance, Point pos, InventoryType inventoryType, Component title) {
        BlockInventory inv = BLOCK_INVENTORY_MAP.get(pos);
        if (inv == null) {
            inv = new BlockInventory(instance, pos, inventoryType, title);
            BLOCK_INVENTORY_MAP.put(pos, inv);
        }
        if (inv.getInventoryType() != inventoryType) {
            throw new IllegalStateException("Inventory type mismatch");
        }
        if (!inv.getTitle().equals(title)) {
            throw new IllegalStateException("Inventory title mismatch");
        }
        return inv;
    }

    public static @NotNull List<ItemStack> remove(Instance instance, Point pos) {
        BlockInventory inv = BLOCK_INVENTORY_MAP.get(pos);
        if (inv == null) {
            return List.of();
        }
        BLOCK_INVENTORY_MAP.remove(pos);
        return List.of(inv.itemStacks);
    }

    @Override
    public void setItemStack(int slot, @NotNull ItemStack itemStack) {
        super.setItemStack(slot, itemStack);
        instance.setBlock(pos, instance.getBlock(pos).withTag(InventoryBlockBehaviour.TAG_ITEMS, List.of(itemStacks)));
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/BlockItems.java
================================================
package net.minestom.vanilla.blocks.behaviours.chestlike;

import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.tag.Tag;
import net.minestom.vanilla.tag.Tags;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.*;
import java.util.stream.Collectors;

/**
 * The key difference between BlockItems and BlockInventory is that BlockItems
 * does not require specifying an inventoryType or title. It is designed for simpler
 * container block management.
 */
public class BlockItems {

    private static final Tag<List<ItemStack>> FALLBACK_TAG_ITEMS = Tag.ItemStack("vri:container_items")
            .list();

    private static Map<String, Tag<List<ItemStack>>> TAG_ITEMS_BY_BLOCK;

    private static Tag<List<ItemStack>> getTagForBlock(Block block) {
        return TAG_ITEMS_BY_BLOCK.getOrDefault(block.name(), FALLBACK_TAG_ITEMS).defaultValue(List.of());
    }

    private final List<ItemStack> items;

    private BlockItems(List<ItemStack> items) {
        this.items = new ArrayList<>(items);
    }

    public static BlockItems from(Block block) {
        return new BlockItems(block.getTag(getTagForBlock(block)));
    }

    public static BlockItems from(Block block, int requireStacks) {
        BlockItems items = from(block);
        if (items.size() != requireStacks) {
            items.requireStacks(requireStacks);
        }
        return items;
    }

    private void requireStacks(int requireStacks) {
        // remove from the top, or add to the top.
        if (items.size() < requireStacks) {
            items.addAll(Collections.nCopies(requireStacks - items.size(), ItemStack.AIR));
        } else if (items.size() > requireStacks) {
            items.subList(requireStacks, items.size()).clear();
        }
    }

    public @UnmodifiableView @NotNull List<ItemStack> itemStacks() {
        return Collections.unmodifiableList(items);
    }

    public int size() {
        return items.size();
    }

    public boolean isEmpty() {
        return items.isEmpty();
    }

    public boolean isAir() {
        return items.isEmpty() || items.stream().allMatch(ItemStack::isAir);
    }

    public Block apply(Block block) {
        return block.withTag(getTagForBlock(block), items);
    }

    public void setItems(List<ItemStack> itemStacks) {
        items.clear();
        items.addAll(itemStacks);
    }

    public ItemStack get(int index) {
        return items.get(index);
    }

    public void set(int index, ItemStack item) {
        items.set(index, item);
    }

    static {
        Map<Block, Tag<List<ItemStack>>> tagItemsByBlock = new HashMap<>();

        // some blocks need to be represented by a specific nbt tag to be visible to the client.
        tagItemsByBlock.put(Block.CAMPFIRE, Tags.Blocks.Campfire.ITEMS);

        BlockItems.TAG_ITEMS_BY_BLOCK = Map.copyOf(tagItemsByBlock.entrySet().stream()
                .map(entry -> Map.entry(entry.getKey().name(), entry.getValue()))
                .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)));
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/DoubleChestInventory.java
================================================
package net.minestom.vanilla.blocks.behaviours.chestlike;

import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;

public class DoubleChestInventory extends Inventory {
    private final BlockInventory left;
    private final BlockInventory right;

    public DoubleChestInventory(BlockInventory left, BlockInventory right, String title) {
        super(InventoryType.CHEST_6_ROW, title);
        this.left = left;
        this.right = right;
    }

    @Override
    public @NotNull ItemStack getItemStack(int slot) {
        if (slot < left.getSize()) {
            return left.getItemStack(slot);
        }
        return right.getItemStack(slot - left.getSize());
    }

    @Override
    public void setItemStack(int slot, @NotNull ItemStack itemStack) {
        if (slot < left.getSize()) {
            left.setItemStack(slot, itemStack);
        } else {
            right.setItemStack(slot - left.getSize(), itemStack);
        }
    }

    @Override
    @Deprecated
    public ItemStack[] getItemStacks() {
        return itemStacks().toArray(ItemStack[]::new);
    }

    public List<ItemStack> itemStacks() {
        return Stream.of(left, right)
                .map(BlockInventory::getItemStacks)
                .map(List::of)
                .flatMap(Collection::stream)
                .toList();
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxidatableBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.oxidisable;

import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerHand;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.inventory.InventoryManipulation;
import net.minestom.vanilla.randomticksystem.RandomTickable;
import net.minestom.vanilla.utils.MathUtils;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * Oxidation (<a href="https://minecraft.fandom.com/wiki/Block_of_Copper#Waxing">Source</a>)
 * <p>
 *     Non-waxed copper blocks have four stages of oxidation (including the initial normal state). Lightning bolts and
 *     axes can remove the oxidation on copper blocks. As the block begins to oxidize (exposed copper), it gets
 *     discolored and green spots begin to appear. As the oxidation continues (weathered copper), the block is a green
 *     color with brown spots. In the last stage (oxidized copper), the block is teal with several green spots.
 *     Oxidation of copper blocks relies only on random ticks. Rain or water does not accelerate oxidation, and covering
 *     copper blocks with other blocks does not prevent oxidation. In Java Edition, groups of non-waxed copper blocks
 *     oxidize far more slowly than single copper blocks that are spaced at least 4 blocks apart. This is because a
 *     block in a group being less oxidized than the others slows down the oxidation process for all other blocks within
 *     4 blocks of taxicab distance. However, if one wishes to increase the oxidation speed, placing oxidized copper
 *     blocks around less oxidized copper blocks does not offer a speed improvement over simply placing the blocks 4
 *     apart. The calculations for the oxidation behavior are as follows:
 *     In Java Edition, when a random tick is given, a copper block has a 64/1125 chance to enter a state called
 *     pre-oxidation. This means a copper block enters pre-oxidation after approximately 20 minutes.
 *     In pre-oxidation, the copper block searches its nearby non-waxed copper blocks for a distance of 4 blocks taxicab
 *     distance. If there is any copper block that has a lower oxidation level, then the pre-oxidation ends, meaning
 *     that this copper block does not weather. Let a be the number of all nearby non-waxed copper blocks, and b be the
 *     number of nearby non-waxed copper blocks that have a higher oxidation level. We derive the value of c from this
 *     equation: c = b + 1/a + 1. We also let the modifying factor m be 0.75 if the copper block has no oxidation level,
 *     or 1 if the copper block is exposed or weathered.[1] Then the oxidation probability is mc2. For example, an
 *     unweathered copper block surrounded by 6 unweathered copper blocks and 6 exposed copper blocks has a 21.7% chance
 *     to oxidize if it enters the pre-oxidation state. In this case, a = 12, b = 6, and m = 0.75.[2] The most efficient
 *     way of laying out the copper blocks for oxidation is in a 7×7×6 face-centered cubic (fcc)/cubic close-packed
 *     (ccp) lattice.
 * <p/>
 */
public class OxidatableBlockBehaviour extends WaxableBlockBehaviour implements RandomTickable, OxygenSensitive {

    private final short previous;
    private final short oxidised;
    private final int oxidisedLevel;


    public OxidatableBlockBehaviour(VanillaBlocks.@NotNull BlockContext context, Block previous, Block oxidised, Block waxed, int oxidisedLevel) {
        super(context, waxed);
        this.previous = (short) previous.stateId();
        this.oxidised = (short) oxidised.stateId();
        this.oxidisedLevel = oxidisedLevel;
    }

    @Override
    public void randomTick(@NotNull RandomTick randomTick) {
        // Exit now if the block cannot be oxidised anymore
        if (oxidised == context.stateId()) return;

        Random random = context.vri().random(randomTick.instance());
        // In Java Edition, when a random tick is given, a copper block has a 64/1125 chance to enter a state called pre-oxidation.
        // This means a copper block enters pre-oxidation after approximately 20 minutes.
        if (random.nextInt(1125) >= 64) {
            return;
        }

        // In pre-oxidation, the copper block searches its nearby non-waxed copper blocks for a distance of 4 blocks
        // taxicab distance. If there is any copper block that has a lower oxidation level, then the pre-oxidation ends,
        // meaning that this copper block does not weather.
        List<Block> nearbyBlocks = MathUtils.getWithinManhattanDistance(randomTick.position(), 4)
                .stream()
                .map(point -> randomTick.instance().isChunkLoaded(point) ?
                        randomTick.instance().getBlock(point) : Block.AIR)
                .toList();
        int minOxidisedAround = nearbyBlocks.stream()
                .filter(block -> block.handler() instanceof OxygenSensitive)
                .map(block -> (OxygenSensitive) block.handler())
                .mapToInt(OxygenSensitive::oxidisedLevel)
                .min()
                .orElse(Integer.MAX_VALUE);

        if (minOxidisedAround < oxidisedLevel) {
            return;
        }

        // Let a be the number of all nearby non-waxed copper blocks, and b be the number of nearby non-waxed copper
        // blocks that have a higher oxidation level. We derive the value of c from this equation: c = b + 1/a + 1.
        // We also let the modifying factor m be 0.75 if the copper block has no oxidation level, or 1 if the copper
        // block is exposed or weathered.[1] Then the oxidation probability is mc2.
        // For example, an unweathered copper block surrounded by 6 unweathered copper blocks and 6 exposed copper
        // blocks has a 21.7% chance to oxidize if it enters the pre-oxidation state. In this case, a = 12, b = 6, and
        // m = 0.75.[2]
        double a = (int) nearbyBlocks.stream()
                .filter(block -> block.handler() instanceof OxygenSensitive os
                        && os.oxidisedLevel() == oxidisedLevel()) // Filter out unrelated blocks
                .count();
        double b = (int) nearbyBlocks.stream()
                .filter(block -> !(block.handler() instanceof WaxedBlockBehaviour))
                .filter(block -> block.handler() instanceof OxygenSensitive os
                        && os.oxidisedLevel() > oxidisedLevel()) // Filter out unrelated blocks
                .map(block -> (OxygenSensitive) block.handler()).filter(Objects::nonNull)
                .filter(handler -> handler.oxidisedLevel() > oxidisedLevel)
                .count();
        double m = oxidisedLevel == 0 ? 0.75 : 1;
        double c = (b + 1) / (a + 1);
        double probability = m * c * c;

        if (random.nextDouble() < probability) {
            Block block = Block.fromStateId(oxidised);
            Objects.requireNonNull(block, "Block with state id " + oxidised + " was not found");
            randomTick.instance().setBlock(randomTick.position(), block);
        }
    }

    @Override
    public int oxidisedLevel() {
        return oxidisedLevel;
    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        PlayerHand hand = interaction.getHand();
        Player player = interaction.getPlayer();
        Block interactionBlock = interaction.getBlock();

        ItemStack item = player.getItemInHand(hand);
        Material material = item.material();

        if (interactionBlock.stateId() != previous
                && material.key().value().toLowerCase().contains("_axe")) { // TODO: Better way to check if it's an axe
            Block previousBlock = Block.fromStateId(previous);
            Objects.requireNonNull(previousBlock, "Block with state id " + previous + " was not found");
            interaction.getInstance().setBlock(interaction.getBlockPosition(), previousBlock);
            InventoryManipulation.damageItemIfNotCreative(player, hand, 1);
            return false;
        }
        return super.onInteract(interaction);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxidatedBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.oxidisable;

import net.minestom.server.instance.block.Block;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

public abstract class OxidatedBlockBehaviour extends WaxableBlockBehaviour implements OxygenSensitive {

    private final int oxidisedLevel;

    public OxidatedBlockBehaviour(VanillaBlocks.@NotNull BlockContext context, Block waxed, int oxidisedLevel) {
        super(context, waxed);
        this.oxidisedLevel = oxidisedLevel;
    }

    @Override
    public int oxidisedLevel() {
        return oxidisedLevel;
    }
}

================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxygenSensitive.java
================================================
package net.minestom.vanilla.blocks.behaviours.oxidisable;

public interface OxygenSensitive {
    int oxidisedLevel();
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/WaxableBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.oxidisable;

import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerHand;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.inventory.InventoryManipulation;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

public abstract class WaxableBlockBehaviour extends VanillaBlockBehaviour {
    protected final short waxedBlock;
    protected WaxableBlockBehaviour(VanillaBlocks.@NotNull BlockContext context, Block waxedTarget) {
        super(context);
        this.waxedBlock = (short) waxedTarget.stateId();
    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        PlayerHand hand = interaction.getHand();
        Player player = interaction.getPlayer();

        ItemStack item = player.getItemInHand(hand);
        Material material = item.material();

        if (Material.HONEYCOMB.equals(material)) {
            Block block = Block.fromStateId(waxedBlock);
            Objects.requireNonNull(block, "Waxed block with state id " + waxedBlock + " does not exist");
            interaction.getInstance().setBlock(interaction.getBlockPosition(), block);
            InventoryManipulation.consumeItemIfNotCreative(player, hand, 1);
            return false;
        }
        return super.onInteract(interaction);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/WaxedBlockBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.oxidisable;

import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerHand;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.inventory.InventoryManipulation;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

public class WaxedBlockBehaviour extends OxidatedBlockBehaviour {
    private final short unWaxed;

    public WaxedBlockBehaviour(VanillaBlocks.@NotNull BlockContext context, Block unWaxed, int oxidisedLevel) {
        super(context, Block.fromStateId(context.stateId()), oxidisedLevel);
        this.unWaxed = (short) unWaxed.stateId();
    }

    @Override
    public boolean onInteract(@NotNull Interaction interaction) {
        PlayerHand hand = interaction.getHand();
        Player player = interaction.getPlayer();

        ItemStack item = player.getItemInHand(hand);
        Material material = item.material();

        if (material.key().value().toLowerCase().contains("_axe")) { // TODO: Better way to check if it's an axe
            Block previousBlock = Block.fromStateId(unWaxed);
            Objects.requireNonNull(previousBlock, "Previous block with state id " + unWaxed + " was not found");
            interaction.getInstance().setBlock(interaction.getBlockPosition(), previousBlock);
            InventoryManipulation.damageItemIfNotCreative(player, hand, 1);
            return false;
        }
        return super.onInteract(interaction);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/BlastingFurnaceBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.BlockVec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blocks.behaviours.InventoryBlockBehaviour;
import net.minestom.vanilla.blocks.behaviours.chestlike.BlockInventory;
import net.minestom.vanilla.events.BlastingFurnaceTickEvent;
import org.jetbrains.annotations.NotNull;

public class BlastingFurnaceBehaviour extends InventoryBlockBehaviour {
    public BlastingFurnaceBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context, InventoryType.BLAST_FURNACE, Component.text("Blast Furnace"));
    }

    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Instance instance = interaction.getInstance();
        Point pos = interaction.getBlockPosition();
        Inventory inventory = BlockInventory.from(instance, pos, InventoryType.BLAST_FURNACE, Component.text("Blast Furnace"));
        Player player = interaction.getPlayer();
        player.openInventory(inventory);
        return false;
    }

    @Override
    public boolean dropContentsOnDestroy() {
        return true;
    }

    @Override
    public boolean isTickable() {
        return true;
    }

    @Override
    public void tick(@NotNull BlockHandler.Tick tick) {
        var events = this.context.vri().process().eventHandler();
        if (!events.hasListener(BlastingFurnaceTickEvent.class)) return; // fast exit since this is hot code
        Instance instance = tick.getInstance();
        Point pos = tick.getBlockPosition();
        Inventory inventory = BlockInventory.from(instance, pos, InventoryType.BLAST_FURNACE, Component.text("Blast Furnace"));
        BlastingFurnaceTickEvent event = new BlastingFurnaceTickEvent(tick.getBlock(), tick.getInstance(), new BlockVec(tick.getBlockPosition()), inventory);
        events.call(event);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/CampfireBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.recipe.*;
import net.minestom.server.recipe.display.RecipeDisplay;
import net.minestom.server.recipe.display.SlotDisplay;
import net.minestom.server.tag.Tag;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blocks.behaviours.chestlike.BlockItems;
import net.minestom.vanilla.inventory.InventoryManipulation;
import net.minestom.vanilla.tag.Tags.Blocks.Campfire;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.stream.IntStream;

public class CampfireBehaviour extends VanillaBlockBehaviour {

    private static final int CONTAINER_SIZE = 4;
    private static final Random RNG = new Random();
    private final RecipeManager recipeManager;

    public CampfireBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context);
        this.recipeManager = context.vri().process().recipe();
    }

    public BlockItems getBlockItems(Block block) {
        return BlockItems.from(block, CONTAINER_SIZE);
    }

    public @NotNull Block withCookingProgress(Block block, int slotIndex, int cookingTime) {
        List<Integer> cookingProgress = new ArrayList<>(block.getTag(Campfire.COOKING_PROGRESS));
        cookingProgress.set(slotIndex, cookingTime);
        return block.withTag(Campfire.COOKING_PROGRESS, cookingProgress);
    }

    /**
     * Appends an id to the first available slot in the campfire.
     * @return the index of the slot the id was appended to.
     */
    public int appendItem(BlockItems items, @NotNull Material material) {
        OptionalInt freeSlot = findFirstFreeSlot(items.itemStacks());

        if (freeSlot.isEmpty())
            throw new IllegalArgumentException("Campfire doesn't have free slot for appending an id in CampfireBehaviour#appendItem");

        ItemStack ingredient = ItemStack.of(material);

        int index = freeSlot.getAsInt();
        items.set(index, ingredient);

        return index;
    }

    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Instance instance = interaction.getInstance();
        Point pos = interaction.getBlockPosition();
        Block block = interaction.getBlock();
        Player player = interaction.getPlayer();
        ItemStack input = player.getItemInHand(interaction.getHand());
        Optional<Recipe> recipeOptional = findCampfireCookingRecipe(input);

        if (recipeOptional.isEmpty())
            return true;

        BlockItems items = getBlockItems(block);
        if (findFirstFreeSlot(items.itemStacks()).isEmpty())
            return true;

        boolean itemNotConsumed = !InventoryManipulation.consumeItemIfNotCreative(player, interaction.getHand(), 1);

        if (itemNotConsumed)
            return true;

        Recipe recipe = recipeOptional.get();
        if (!(recipe.createRecipeDisplays().getFirst() instanceof RecipeDisplay.Furnace furnaceRecipe)) return false;
        Material material = getMaterialFromSlotDisplay(furnaceRecipe.ingredient());
        if (material == null) return false;
        int index = appendItem(items, material);
        block = withCookingProgress(block, index, furnaceRecipe.duration());
        instance.setBlock(pos, items.apply(block));
        return false;
    }

    @Override
    public void onDestroy(@NotNull BlockHandler.Destroy destroy) {
        Instance instance = destroy.getInstance();
        Point pos = destroy.getBlockPosition();
        Block block = destroy.getBlock();

        // TODO: Introduce a way to get the block this is getting replaced with, enabling us to remove the tick delay.
        instance.scheduleNextTick(ignored -> {
            Block newBlock = instance.getBlock(pos);
            if (newBlock.compare(block)) {
                // Same block, don't remove campfire
                return;
            }

            // Different block, remove campfire
            List<ItemStack> items = BlockItems.from(newBlock).itemStacks();

            for (ItemStack item : items) {

                if (item == null) {
                    continue;
                }

                dropItem(instance, pos, item);
            }
        });
    }

    @Override
    public void tick(@NotNull BlockHandler.Tick tick) {
        Instance instance = tick.getInstance();
        Block block = tick.getBlock();
        Point pos = tick.getBlockPosition();
        BlockItems items = getBlockItems(block);

        if (items.isAir())
            return;

        List<Integer> cookingProgress = new ArrayList<>(block.getTag(Campfire.COOKING_PROGRESS));

        boolean lit = Boolean.parseBoolean(block.getProperty("lit"));
        if (!lit) {
            for (ItemStack item : items.itemStacks())
                dropItem(instance, pos, item);
            items.setItems(Collections.nCopies(4, ItemStack.AIR));
            instance.setBlock(pos, items.apply(block));
            return;
        }

        for (ListIterator<Integer> i = cookingProgress.listIterator(); i.hasNext(); ) {
            int index = i.nextIndex();
            Integer progress = i.next();
            Material inputMaterial = items.get(index).material();

            if (Material.AIR.equals(inputMaterial))
                continue;

            if (progress <= 0) {
                endCampfireCookingProgress(tick.getInstance(), tick.getBlockPosition(), ItemStack.of(inputMaterial));
                items.set(index, ItemStack.AIR);
                continue;
            }

            progress -= 1;
            i.set(progress);
        }

        block = items.apply(block);
        block = block.withTag(Campfire.COOKING_PROGRESS, cookingProgress);
        instance.setBlock(pos, block);
    }

    @Override
    public @NotNull Collection<Tag<?>> getBlockEntityTags() {
        return List.of(Campfire.ITEMS);
    }

    @Override
    public boolean isTickable() {
        return true;
    }

    private void endCampfireCookingProgress(Instance instance, Point pos, ItemStack input) {
        Optional<Recipe> recipeOptional = findCampfireCookingRecipe(input);
        if (recipeOptional.isEmpty())
            throw new IllegalArgumentException("Cannot end campfire cooking progress because input recipe doesn't found");
        Material material = getRecipeResult(recipeOptional.get());
        if (material == null) {
            return;
        }
        dropItem(instance, pos, ItemStack.of(material));
    }

    private void dropItem(Instance instance, Point pos, ItemStack item) {
        ItemEntity resultItemEntity = new ItemEntity(item);
        resultItemEntity.setInstance(instance);
        resultItemEntity.teleport(new Pos(pos.x() + RNG.nextDouble(), pos.y() + .5f, pos.z() + RNG.nextDouble()));
    }

    private OptionalInt findFirstFreeSlot(List<ItemStack> items) {
        return IntStream.range(0, items.size()).filter(index -> items.get(index).isAir()).findFirst();
    }

    private Material getRecipeResult(Recipe recipe) {
        RecipeDisplay d = recipe.createRecipeDisplays().getFirst();
        if (d instanceof RecipeDisplay.Furnace f) {
            return getMaterialFromSlotDisplay(f.result());
        }
        return null;
    }

    private Material getRecipeInput(Recipe recipe) {
        RecipeDisplay d = recipe.createRecipeDisplays().getFirst();
        if (d instanceof RecipeDisplay.Furnace f) {
            return getMaterialFromSlotDisplay(f.ingredient());
        }
        return null;
    }

    private Material getMaterialFromSlotDisplay(SlotDisplay slotDisplay) {
        return switch (slotDisplay) {
            case SlotDisplay.Item i -> i.material();
            case SlotDisplay.ItemStack i -> i.itemStack().material();
            default -> null;
        };
    }

    private Optional<Recipe> findCampfireCookingRecipe(ItemStack input) {
        if (input == null)
            return Optional.empty();
        return recipeManager
                .getRecipes().stream()
                .filter(r -> r.recipeBookCategory() == RecipeBookCategory.CAMPFIRE)
                .filter(recipe -> input.material().equals(getRecipeInput(recipe))).findFirst();
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/CraftingTableBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.minestom.server.entity.Player;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.inventory.InventoryCloseEvent;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

public class CraftingTableBehaviour extends VanillaBlockBehaviour {
    public CraftingTableBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context);
    }

    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Inventory inventory = new Inventory(InventoryType.CRAFTING, "Crafting Table");
        Player player = interaction.getPlayer();
        player.openInventory(inventory);
        player.eventNode().addListener(
                EventListener.builder(InventoryCloseEvent.class)
                        .filter(event -> inventory == event.getInventory())
                        .expireCount(1)
                        .handler(event -> {
                            // TODO: Drop all items instead of adding them to the player's inventory?
                            for (ItemStack itemStack : inventory.getItemStacks()) {
                                player.getInventory().addItemStack(itemStack);
                            }
                        })
                        .build()
        );
        return false;
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/FurnaceBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.BlockVec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blocks.behaviours.InventoryBlockBehaviour;
import net.minestom.vanilla.blocks.behaviours.chestlike.BlockInventory;
import net.minestom.vanilla.events.FurnaceTickEvent;
import org.jetbrains.annotations.NotNull;

public class FurnaceBehaviour extends InventoryBlockBehaviour {
    public FurnaceBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context, InventoryType.FURNACE, Component.text("Furnace"));
    }

    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Instance instance = interaction.getInstance();
        Point pos = interaction.getBlockPosition();
        Inventory inventory = BlockInventory.from(instance, pos, InventoryType.FURNACE, Component.text("Furnace"));
        Player player = interaction.getPlayer();
        player.openInventory(inventory);
        return false;
    }

    @Override
    public boolean dropContentsOnDestroy() {
        return true;
    }

    @Override
    public boolean isTickable() {
        return true;
    }

    @Override
    public void tick(@NotNull BlockHandler.Tick tick) {
        var events = this.context.vri().process().eventHandler();
        if (!events.hasListener(FurnaceTickEvent.class)) return; // fast exit since this is hot code
        Instance instance = tick.getInstance();
        Point pos = tick.getBlockPosition();
        Inventory inventory = BlockInventory.from(instance, pos, InventoryType.FURNACE, Component.text("Furnace"));
        FurnaceTickEvent event = new FurnaceTickEvent(tick.getBlock(), tick.getInstance(), new BlockVec(tick.getBlockPosition()), inventory);
        events.call(event);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/SmithingTableBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.minestom.server.entity.Player;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.inventory.InventoryCloseEvent;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

public class SmithingTableBehaviour extends VanillaBlockBehaviour {
    public SmithingTableBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context);
    }

    // TODO: block placement facing
    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Inventory inventory = new Inventory(InventoryType.SMITHING, "Upgrade Gear");

        Player player = interaction.getPlayer();
        player.openInventory(inventory);
        player.eventNode().addListener(
                EventListener.builder(InventoryCloseEvent.class)
                        .filter(event -> inventory == event.getInventory())
                        .expireCount(1)
                        .handler(event -> {
                            // TODO: Drop all items instead of adding them to the player's inventory?
                            for (int i = 0; i < 3; i++) {
                                player.getInventory().addItemStack(inventory.getItemStack(i));
                            }
                        })
                        .build()
        );
        return false;
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/SmokerBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.BlockVec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlocks;
import net.minestom.vanilla.blocks.behaviours.InventoryBlockBehaviour;
import net.minestom.vanilla.blocks.behaviours.chestlike.BlockInventory;
import net.minestom.vanilla.events.SmokerTickEvent;
import org.jetbrains.annotations.NotNull;

public class SmokerBehaviour extends InventoryBlockBehaviour {
    public SmokerBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context, InventoryType.SMOKER, Component.text("Smoker"));
    }

    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Instance instance = interaction.getInstance();
        Point pos = interaction.getBlockPosition();
        Inventory inventory = BlockInventory.from(instance, pos, InventoryType.SMOKER, Component.text("Smoker"));
        Player player = interaction.getPlayer();
        player.openInventory(inventory);
        return false;
    }

    @Override
    public boolean dropContentsOnDestroy() {
        return true;
    }

    @Override
    public boolean isTickable() {
        return true;
    }

    @Override
    public void tick(@NotNull BlockHandler.Tick tick) {
        var events = this.context.vri().process().eventHandler();
        if (!events.hasListener(SmokerTickEvent.class)) return; // fast exit since this is hot code
        Instance instance = tick.getInstance();
        Point pos = tick.getBlockPosition();
        Inventory inventory = BlockInventory.from(instance, pos, InventoryType.SMOKER, Component.text("Smoker"));
        SmokerTickEvent event = new SmokerTickEvent(tick.getBlock(), tick.getInstance(), new BlockVec(tick.getBlockPosition()), inventory);
        events.call(event);
    }
}


================================================
FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/StonecutterBehaviour.java
================================================
package net.minestom.vanilla.blocks.behaviours.recipe;

import net.minestom.server.entity.Player;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.inventory.InventoryCloseEvent;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.vanilla.blocks.VanillaBlockBehaviour;
import net.minestom.vanilla.blocks.VanillaBlocks;
import org.jetbrains.annotations.NotNull;

public class StonecutterBehaviour extends VanillaBlockBehaviour {
    public StonecutterBehaviour(VanillaBlocks.@NotNull BlockContext context) {
        super(context);
    }

    // TODO: block placement facing

    @Override
    public boolean onInteract(@NotNull BlockHandler.Interaction interaction) {
        Inventory inventory = new Inventory(InventoryType.STONE_CUTTER, "Stonecutter");

        Player player = interaction.getPlayer();
        player.openInventory(inventory);
        player.eventNode().addListener(
                EventListener.builder(InventoryCloseEvent.class)
                        .filter(event -> inventory == event.getInventory())
                        .expireCount(1)
                        .handler(event -> {
                            // TODO: Drop all items instead of adding them to the player's inventory?
                            player.getInventory().addItemStack(inventory.getItemStack(0));
                        })
                        .build()
        );
        return false;
    }
}


================================================
FILE: build.gradle.kts
================================================
plugins {
    java
    `java-library`
    `maven-publish`
    id("com.github.harbby.gradle.serviceloader") version ("1.1.8")
    id("io.github.goooler.shadow") version ("8.1.8")
}

subprojects {

    plugins.apply("java")
    plugins.apply("java-library")
    plugins.apply("maven-publish")
    plugins.apply("com.github.harbby.gradle.serviceloader")
    plugins.apply("io.github.goooler.shadow")

    group = "net.minestom.vanilla"
    version = "indev"

    java {
        sourceCompatibility = JavaVersion.VERSION_21
        targetCompatibility = JavaVersion.VERSION_21

//        withJavadocJar()
        withSourcesJar()

        sourceSets.main {
            java.srcDir("src/main/java")
        }
    }

    tasks.withType<Jar> {
        duplicatesStrategy = DuplicatesStrategy.INCLUDE
    }

    tasks.withType<Wrapper> {
        gradleVersion = rootProject.gradle.gradleVersion
    }

    repositories {
        mavenCentral()
        maven(url = "https://jitpack.io")
        mavenLocal()
    }

    dependencies {
    }

    publishing {
        publications {
            register("maven", MavenPublication::class) {
                from(components["java"])
            }
        }
    }

    serviceLoader.serviceInterfaces.add("net.minestom.vanilla.VanillaReimplementation\$Feature")
    serviceLoader.serviceInterfaces.add("org.slf4j.spi.SLF4JServiceProvider")

    tasks.getByName("build").dependsOn("shadowJar")

    tasks.withType<Test> {
        dependsOn("serviceLoaderBuild")
        useJUnitPlatform()
    }
}


================================================
FILE: commands/build.gradle.kts
================================================
dependencies {
    compileOnly(project(":core"))
    compileOnly(project(":instance-meta"))
}

================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/DifficultyCommand.java
================================================
package net.minestom.vanilla.commands;

import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.world.Difficulty;
import org.jetbrains.annotations.NotNull;

/**
 * Command that make an instance change difficulty
 */
public class DifficultyCommand extends Command {
    public DifficultyCommand() {
        super("difficulty");

        setCondition(this::isAllowed);

        setDefaultExecutor(this::usage);

        Argument<?> difficulty = ArgumentType.Word("difficulty").from("peaceful", "easy", "normal", "hard");


        difficulty.setCallback(this::difficultyCallback);

        addSyntax(this::execute, difficulty);
    }

    private void usage(CommandSender player, CommandContext arguments) {
        player.sendMessage("Usage: /difficulty (peaceful|easy|normal|hard)");
    }

    private void execute(CommandSender player, CommandContext arguments) {
        String difficultyName = arguments.get("difficulty");
        Difficulty difficulty = Difficulty.valueOf(difficultyName.toUpperCase());
        MinecraftServer.setDifficulty(difficulty);
        player.sendMessage("You are now playing in " + difficultyName);
    }

    private void difficultyCallback(@NotNull CommandSender sender, @NotNull ArgumentSyntaxException exception) {
        sender.sendMessage("'" + exception.getInput() + "' is not a valid difficulty!");
    }

    private boolean isAllowed(CommandSender player, String commandName) {
        return true; // TODO: permissions
    }
}



================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/ForceloadCommand.java
================================================
package net.minestom.vanilla.commands;

import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.coordinate.CoordConversion;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.location.RelativeVec;
import net.minestom.vanilla.instancemeta.tickets.TicketManager;
import net.minestom.vanilla.instancemeta.tickets.TicketUtils;

import java.util.List;

/**
 * "forceload":
 * Description: "Forces chunks to constantly be loaded or not. "
 * BE: false
 * EE: false
 * JE: true
 * OP_Level: 2
 * BE_EE_OP_Level: 0
 * MP_Only: false
 */
public class ForceloadCommand extends Command {

    public ForceloadCommand() {
        super("forceload");

        // forceload add <from> [<to>]
        //    Forces the chunk at the <from> position (through to <to> if set) in the dimension of the command's execution to be loaded constantly.
        this.addSyntax(
                this::usageAddFrom,
                ArgumentType.Literal("add"),
                ArgumentType.RelativeVec2("from")
        );
        this.addSyntax(
                this::usageAddFromTo,
                ArgumentType.Literal("add"),
                ArgumentType.RelativeVec2("from"),
                ArgumentType.RelativeVec2("to")
        );

        // forceload remove <from> [<to>]
        //    Unforces the chunk at the <from> position (through to <to> if set) in the dimension of the command's execution to be loaded constantly.
        this.addSyntax(
                this::usageRemoveFrom,
                ArgumentType.Literal("remove"),
                ArgumentType.RelativeVec2("from")
        );
        this.addSyntax(
                this::usageRemoveFromTo,
                ArgumentType.Literal("remove"),
                ArgumentType.RelativeVec2("from"),
                ArgumentType.RelativeVec2("to")
        );
    }

    private void addForceLoad(Instance instance, int chunkX, int chunkZ) {
        addForceLoad(instance, CoordConversion.chunkIndex(chunkX, chunkZ));
    }

    private void addForceLoad(Instance instance, long chunkIndex) {
        TicketManager.Ticket ticketToAdd = TicketManager.Ticket.from(TicketManager.FORCED_TICKET, chunkIndex);
        TicketUtils.waitingTickets(instance, List.of(ticketToAdd));
    }

    private void removeForceLoad(Instance instance, int chunkX, int chunkZ) {
        removeForceLoad(instance, CoordConversion.chunkIndex(chunkX, chunkZ));
    }

    private void removeForceLoad(Instance instance, long chunkIndex) {

        TicketManager.Ticket ticketToRemove = TicketManager.Ticket.from(TicketManager.FORCED_TICKET, chunkIndex);
        TicketUtils.removingTickets(instance, List.of(ticketToRemove));
    }

    private void usageAddFrom(CommandSender sender, CommandContext context) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage("This command must be executed by a player!");
            return;
        }
        RelativeVec fromVec = context.get("from");
        Vec position = fromVec.from(player.getPosition());

        // Get chunk position
        int chunkX = CoordConversion.globalToChunk(position.x());
        int chunkZ = CoordConversion.globalToChunk(position.z());

        // Add the force load
        Instance instance = player.getInstance();
        addForceLoad(instance, chunkX, chunkZ);
    }

    private void usageAddFromTo(CommandSender sender, CommandContext context) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage("This command must be executed by a player!");
            return;
        }
        RelativeVec fromVec = context.get("from");
        RelativeVec toVec = context.get("to");
        Vec from = fromVec.from(player.getPosition());
        Vec to = toVec.from(player.getPosition());

        int startX = Math.min(from.blockX(), to.blockX());
        int endX = Math.max(from.blockX(), to.blockX());
        int startZ = Math.min(from.blockZ(), to.blockZ());
        int endZ = Math.max(from.blockZ(), to.blockZ());

        Instance instance = player.getInstance();

        for (int offX = startX; offX < endX; offX += 16) {
            for (int offZ = startZ; offZ < endZ; offZ += 16) {
                // Get chunk position
                int chunkX = CoordConversion.globalToChunk(offX);
                int chunkZ = CoordConversion.globalToChunk(offZ);
                removeForceLoad(instance, chunkX, chunkZ);
            }
        }
    }

    private void usageRemoveFrom(CommandSender sender, CommandContext context) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage("This command must be executed by a player!");
            return;
        }
        RelativeVec fromVec = context.get("from");
        Vec position = fromVec.from(player.getPosition());

        // Get chunk position
        int chunkX = CoordConversion.globalToChunk(position.x());
        int chunkZ = CoordConversion.globalToChunk(position.z());

        // Remove force load
        Instance instance = player.getInstance();

        removeForceLoad(instance, chunkX, chunkZ);
    }

    private void usageRemoveFromTo(CommandSender sender, CommandContext context) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage("This command must be executed by a player!");
            return;
        }
        RelativeVec fromVec = context.get("from");
        RelativeVec toVec = context.get("to");
        Vec from = fromVec.from(player.getPosition());
        Vec to = toVec.from(player.getPosition());

        int minX = Math.min(from.blockX(), to.blockX());
        int maxX = Math.max(from.blockX(), to.blockX());
        int minZ = Math.min(from.blockZ(), to.blockZ());
        int maxZ = Math.max(from.blockZ(), to.blockZ());

        Instance instance = player.getInstance();

        for (int offX = minX; offX <= maxX; offX += 16) {
            for (int offZ = minZ; offZ <= maxZ; offZ += 16) {
                // Get chunk position
                int chunkX = CoordConversion.globalToChunk(offX);
                int chunkZ = CoordConversion.globalToChunk(offZ);

                // Remove the force load
                removeForceLoad(instance, chunkX, chunkZ);
            }
        }
    }
}


================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/GamemodeCommand.java
================================================
package net.minestom.vanilla.commands;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.arguments.ArgumentEnum;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.minecraft.ArgumentEntity;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.utils.entity.EntityFinder;

import java.util.List;
import java.util.Locale;

/**
 * Command that make a player change gamemode, made in
 * the style of the vanilla /gamemode command.
 *
 * @see <a href="https://minecraft.fandom.com/wiki/Commands/gamemode">...</a>
 */
public class GamemodeCommand extends Command {

    public GamemodeCommand() {
        super("gamemode", "gm");

        //GameMode parameter
        ArgumentEnum<GameMode> gamemode = ArgumentType.Enum("gamemode", GameMode.class).setFormat(ArgumentEnum.Format.LOWER_CASED);
        gamemode.setCallback((sender, exception) -> sender.sendMessage(
                Component.text("Invalid gamemode ", NamedTextColor.RED)
                        .append(Component.text(exception.getInput(), NamedTextColor.WHITE))
                        .append(Component.text("!"))));

        ArgumentEntity player = ArgumentType.Entity("targets").onlyPlayers(true);

        //Upon invalid usage, print the correct usage of the command to the sender
        setDefaultExecutor((sender, context) -> {
            String commandName = context.getCommandName();

            sender.sendMessage(Component.text("Usage: /" + commandName + " <gamemode> [targets]", NamedTextColor.RED));
        });

        //Command Syntax for /gamemode <gamemode>
        addSyntax((sender, context) -> {
            //Limit execution to players only
            if (!(sender instanceof Player playerSender)) {
                sender.sendMessage(Component.text("Please run this command in-game.", NamedTextColor.RED));
                return;
            }

            //Check permission, this could be replaced with hasPermission
            if (playerSender.getPermissionLevel() < 2) {
                sender.sendMessage(Component.text("You don't have permission to use this command.", NamedTextColor.RED));
                return;
            }

            GameMode mode = context.get(gamemode);

            //Set the gamemode for the sender
            executeSelf(playerSender, mode);
        }, gamemode);

        //Command Syntax for /gamemode <gamemode> [targets]
        addSyntax((sender, context) -> {
            //Check permission for players only
            //This allows the console to use this syntax too
            if ((sender instanceof Player playerSender) && playerSender.getPermissionLevel() < 2) {
                sender.sendMessage(Component.text("You don't have permission to use this command.", NamedTextColor.RED));
                return;
            }

            EntityFinder finder = context.get(player);
            GameMode mode = context.get(gamemode);

            //Set the gamemode for the targets
            executeOthers(sender, mode, finder.find(sender));
        }, gamemode, player);
    }

    /**
     * Sets the gamemode for the specified entities, and
     * notifies them (and the sender) in the chat.
     */
    private void executeOthers(CommandSender sender, GameMode mode, List<Entity> entities) {
        if (entities.isEmpty()) {
            //If there are no players that could be modified, display an error message
            if (sender instanceof Player playerSender)
                sender.sendMessage(Component.translatable("argument.entity.notfound.player", NamedTextColor.RED));
            else sender.sendMessage(Component.text("No player was found", NamedTextColor.RED));
        } else for (Entity entity : entities) {
            if (entity instanceof Player p) {
                if (p == sender) {
                    //If the player is the same as the sender, call
                    //executeSelf to display one message instead of two
                    executeSelf(p, mode);
                } else {
                    p.setGameMode(mode);

                    String gamemodeString = "gameMode." + mode.name().toLowerCase(Locale.ROOT);
                    Component gamemodeComponent = Component.translatable(gamemodeString);
                    Component playerName = p.getDisplayName() == null ? p.getName() : p.getDisplayName();

                    //Send a message to the changed player and the sender
                    p.sendMessage(Component.translatable("gameMode.changed", gamemodeComponent));
                    sender.sendMessage(Component.translatable("commands.gamemode.success.other", playerName, gamemodeComponent));
                }
            }
        }
    }

    /**
     * Sets the gamemode for the executing Player, and
     * notifies them in the chat.
     */
    private void executeSelf(Player sender, GameMode mode) {
        sender.setGameMode(mode);

        //The translation keys 'gameMode.survival', 'gameMode.creative', etc.
        //correspond to the translated game mode names.
        String gamemodeString = "gameMode." + mode.name().toLowerCase(Locale.ROOT);
        Component gamemodeComponent = Component.translatable(gamemodeString);

        //Send the translated message to the player.
        sender.sendMessage(Component.translatable("commands.gamemode.success.self", gamemodeComponent));
    }
}


================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/HelpCommand.java
================================================
package net.minestom.vanilla.commands;

import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Returns the list of all available commands
 */
public class HelpCommand extends Command {
    public HelpCommand() {
        super("help");

        setDefaultExecutor(this::execute);
    }

    private void execute(CommandSender sender, CommandContext context) {
        sender.sendMessage("=== Help ===");

        List<VanillaCommands> commands = new ArrayList<>();

        Collections.addAll(commands, VanillaCommands.values());

        commands.sort(this::compareCommands);

        commands.forEach(command -> sender.sendMessage("/" + command.name().toLowerCase()));

        sender.sendMessage("============");
    }

    private int compareCommands(VanillaCommands a, VanillaCommands b) {
        return a.name().compareTo(b.name());
    }
}


================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/MeCommand.java
================================================
package net.minestom.vanilla.commands;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.minestom.server.adventure.audience.Audiences;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.server.command.builder.arguments.ArgumentStringArray;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.entity.Player;

/**
 * Command that displays a player action
 */
public class MeCommand extends Command {
    public MeCommand() {
        super("me");

        setDefaultExecutor(this::usage);

        ArgumentStringArray message = ArgumentType.StringArray("message");

        addSyntax(this::execute, message);
    }

    private void usage(CommandSender player, CommandContext arguments) {
        player.sendMessage("Usage: /me <message>");
    }

    private void execute(CommandSender sender, CommandContext arguments) {
        if (!(sender instanceof Player player)) {
            sender.sendMessage("This command must be executed by a player!");
            return;
        }
        String[] messageParts = arguments.get("message");

        TextComponent.Builder builder = Component.text();

        builder.append(Component.text(" * " + player.getUsername()));

        builder.append(Component.text(" "));
        builder.append(Component.text(messageParts[0]));

        for (int i = 1; i < messageParts.length; i++) {
            builder.append(Component.text(messageParts[i]));
        }

        Component message = builder.build();
        Audiences.all().sendMessage(message);
    }

    @SuppressWarnings("unused")
    private boolean isAllowed(CommandSender player) {
        return player instanceof Player; // TODO: permissions
    }
}



================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/SaveAllCommand.java
================================================
package net.minestom.vanilla.commands;

import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;
import net.minestom.vanilla.logging.Logger;

/**
 * Save the server
 */
public class SaveAllCommand extends Command {
    public SaveAllCommand() {
        super("save-all");
        setCondition(this::condition);
        setDefaultExecutor(this::execute);
    }

    private boolean condition(CommandSender player, String commandName) {
        return true; // TODO: permissions
    }

    private void execute(CommandSender player, CommandContext arguments) {
        MinecraftServer.getInstanceManager().getInstances().forEach(i -> {
            i.saveChunksToStorage();
            Logger.info("Saved dimension " + i.getDimensionType().name());
        });
    }
}


================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/StopCommand.java
================================================
package net.minestom.vanilla.commands;

import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.Command;
import net.minestom.server.command.builder.CommandContext;

/**
 * Stops the server
 */
public class StopCommand extends Command {
    public StopCommand() {
        super("stop");
        setCondition(this::condition);
        setDefaultExecutor(this::execute);
    }

    private boolean condition(CommandSender player, String commandName) {
        return true; // TODO: permissions
    }

    private void execute(CommandSender player, CommandContext arguments) {
        MinecraftServer.stopCleanly();
    }
}


================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/VanillaCommands.java
================================================
package net.minestom.vanilla.commands;

import net.minestom.server.command.CommandManager;
import net.minestom.server.command.builder.Command;
import org.jetbrains.annotations.NotNull;

import java.util.function.Supplier;

/**
 * All commands available in the vanilla reimplementation
 */
public enum VanillaCommands {

    FORCELOAD(ForceloadCommand::new),
    GAMEMODE(GamemodeCommand::new),
    DIFFICULTY(DifficultyCommand::new),
    ME(MeCommand::new),
    STOP(StopCommand::new),
    HELP(HelpCommand::new),
    SAVE_ALL(SaveAllCommand::new),
    ;

    private final Supplier<Command> commandCreator;

    VanillaCommands(Supplier<Command> commandCreator) {
        this.commandCreator = commandCreator;
    }

    /**
     * Register all vanilla commands into the given manager
     *
     * @param manager the command manager to register commands on
     */
    public static void registerAll(@NotNull CommandManager manager) {
        for (VanillaCommands vanillaCommand : values()) {
            Command command = vanillaCommand.commandCreator.get();
            manager.register(command);
        }
    }
}


================================================
FILE: commands/src/main/java/net/minestom/vanilla/commands/VanillaCommandsFeature.java
================================================
package net.minestom.vanilla.commands;


import net.kyori.adventure.key.Key;
import net.minestom.vanilla.VanillaReimplementation;
import net.minestom.vanilla.instancemeta.InstanceMetaFeature;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

public class VanillaCommandsFeature implements VanillaReimplementation.Feature {

    @Override
    public void hook(@NotNull HookContext context) {
        new Logic().hook(context.vri());
    }

    @Override
    public @NotNull Key key() {
        return Key.key("vri:commands");
    }

    private static class Logic {
        private Logic() {
        }

        private void hook(@NotNull VanillaReimplementation vri) {
            VanillaCommands.registerAll(vri.process().command());
        }
    }

    @Override
    public @NotNull Set<Class<? extends VanillaReimplementation.Feature>> dependencies() {
        return Set.of(InstanceMetaFeature.class);
    }
}


================================================
FILE: core/build.gradle.kts
================================================
dependencies {
    // Minestom
    api("net.minestom:minestom:${project.property("minestom_version")}")

    // Raycasting
    api("com.github.EmortalMC:Rayfast:${project.property("rayfast_version")}")

    // Noise
    api("com.github.Articdive:JNoise:${project.property("jnoise_version")}")

    // Annotations
    api("org.jetbrains:annotations:${project.property("annotations_version")}")

    // SLF4j
    api("org.slf4j:slf4j-api:${project.property("slf4j_version")}")

    // Json
    api("com.squareup.moshi:moshi:1.14.0")
    api("com.squareup.moshi:moshi-adapters:1.14.0")

    // Tests
    testImplementation(platform("org.junit:junit-bom:5.9.1"))
    testImplementation("org.junit.jupiter:junit-jupiter")
}

tasks.test {
    useJUnitPlatform()
}


================================================
FILE: core/src/main/java/net/minestom/vanilla/VanillaRegistry.java
================================================
package net.minestom.vanilla;

import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.tag.TagReadable;
import org.jetbrains.annotations.NotNull;

/**
 * This registry object is used to register data and logic.
 */
public sealed interface VanillaRegistry permits VanillaReimplementationImpl.VanillaRegistryImpl {

    /**
     * Registers an entity type to its entity spawner.
     *
     * @param type     the type of the entity
     * @param supplier the entity spawner of the entity
     */
    void register(@NotNull EntityType type, @NotNull EntitySpawner supplier);

    interface EntitySpawner {
        @NotNull Entity spawn(@NotNull VanillaRegistry.EntityContext context);
    }

    interface EntityContext extends TagReadable {
        @NotNull EntityType type();

        @NotNull Pos position();
    }
}


================================================
FILE: core/src/main/java/net/minestom/vanilla/VanillaReimplementation.java
================================================
package net.minestom.vanilla;

import net.kyori.adventure.key.Key;
import net.minestom.server.ServerProcess;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.instance.Instance;
import net.minestom.server.tag.TagWritable;
import net.minestom.server.world.DimensionType;
import net.minestom.vanilla.logging.StatusUpdater;
import net.minestom.vanilla.utils.DependencySorting;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;

public interface VanillaReimplementation {

    /**
     * Creates a new instance of {@link VanillaReimplementation} and hooks into the server process.
     *
     * @param process the server process
     * @return the new instance
     */
    static @NotNull VanillaReimplementation hook(@NotNull ServerProcess process) {
        return VanillaReimplementation.hook(process, feature -> true);
    }

    /**
     * Creates a new instance of {@link VanillaReimplementation} and hooks all features into the server process.
     * <p>
     * This method only hooks the features that pass the given predicate.
     * </p>
     *
     * @param process   the server process
     * @param predicate the predicate to test the features
     * @return the new instance
     */
    static @NotNull VanillaReimplementation hook(@NotNull ServerProcess process, Predicate<Feature> predicate) {
        return VanillaReimplementationImpl.hook(process, predicate);
    }

    // Vri Methods

    /**
     * @return the server process
     */
    @NotNull ServerProcess process();

    /**
     * Acquires the given {@link Feature} from this reimplementation.
     * @param clazz the feature's class
     * @param <T> the feature's type
     * @return the feature
     */
    <T extends Feature> @NotNull T feature(Class<T> clazz);

    /**
     * Creates an {@link net.minestom.vanilla.VanillaRegistry.EntityContext} for the given type and position
     *
     * @param type     the type of the entity
     * @param position the position of the entity at spawn
     * @return the context
     */
    default @NotNull VanillaRegistry.EntityContext entityContext(EntityType type, Point position) {
        return entityContext(type, position, writer -> {
        });
    }

    /**
     * Creates an {@link net.minestom.vanilla.VanillaRegistry.EntityContext} for the given type and position, with the
     * given tag values.
     *
     * @param type     the type of the entity
     * @param position the position of the entity at spawn
     * @return the context
     */
    @NotNull VanillaRegistry.EntityContext entityContext(EntityType type, Point position,
                                                         @NotNull Consumer<TagWritable> tagWriter);

    /**
     * Creates a new vanilla entity, using the specified context, returning null if the entity type is not implemented.
     *
     * @param context the context
     * @return the new entity
     */
    @Nullable Entity createEntity(@NotNull VanillaRegistry.EntityContext context);

    /**
     * Creates a new vanilla entity, using the specified context, returning a dummy entity if the entity type is not
     * implemented.
     *
     * @param context the context
     * @return the new entity
     */
    @NotNull Entity createEntityOrDummy(@NotNull VanillaRegistry.EntityContext context);

    /**
     * Creates and registers a vanilla instance.
     */
    @NotNull Instance createInstance(@NotNull Key namespace, @NotNull DimensionType dimension);

    /**
     * Gets a registered vanilla instance.
     *
     * @param namespace the namespace of the instance
     * @return the instance, or null if not found
     */
    @Nullable Instance getInstance(Key namespace);

    /**
     * Retrieves or generates a random object unique to the given object.
     * <br>
     * Note that this method does not keep the given key in memory, however it does always return the same random for
     * any given (equal) key object.
     *
     * @param key the key
     * @return the random
     */
    @NotNull Random random(@NotNull Object key);

    /**
     * A feature is a collection of logic that can be hooked into a server process.
     */
    interface Feature extends DependencySorting.NamespaceDependent<Class<? extends Feature>> {

        /**
         * Hooks into this server process.
         * <p>
         * DO NOT manually call this method, use {@link VanillaReimplementation#hook} instead.
         * </p>
         *
         * @param vri      the vanilla reimplementation object
         * @param registry the registry object
         */
        @Deprecated
        default void hook(@NotNull VanillaReimplementation vri, @NotNull VanillaRegistry registry) {
        }

        /**
         * Hooks into this server process.
         * <p>
         * DO NOT manually call this method, use {@link VanillaReimplementation#hook} instead.
         * </p>
         *
         * @param context the context containing all related objects
         */
        void hook(@NotNull HookContext context);

        interface HookContext {
            @NotNull VanillaReimplementation vri();
            @NotNull VanillaRegistry registry();
            @NotNull StatusUpdater status();
        }

        /**
         * Obtains the dependencies of this feature.
         * These dependencies will be loaded before this feature.
         * @return the dependencies
         */
        default @NotNull Set<Class<? extends Feature>> dependencies() {
            return Set.of();
        }

        /**
         * @return a unique {@link Key} for this feature
         */
        @NotNull Key key();

        /**
         * @return a unique {@link Class} for this feature
         */
        default @NotNull Class<? extends Feature> identity() {
            return getClass();
        }
    }
}


================================================
FILE: core/src/main/java/net/minestom/vanilla/VanillaReimplementationImpl.java
================================================
package net.minestom.vanilla;

import net.kyori.adventure.key.Key;
import net.minestom.server.ServerProcess;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.LightingChunk;
import net.minestom.server.instance.anvil.AnvilLoader;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.tag.TagHandler;
import net.minestom.server.tag.TagWritable;
import net.minestom.server.tag.Taggable;
import net.minestom.server.world.DimensionType;
import net.minestom.vanilla.dimensions.VanillaDimensionTypes;
import net.minestom.vanilla.instance.SetupVanillaInstanceEvent;
import net.minestom.vanilla.logging.Loading;
import net.minestom.vanilla.logging.Logger;
import net.minestom.vanilla.logging.StatusUpdater;
import net.minestom.vanilla.utils.DependencySorting;
import net.minestom.vanilla.utils.MinestomUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

class VanillaReimplementationImpl implements VanillaReimplementation {

    private final ServerProcess process;
    private final Map<Key, Instance> worlds = new ConcurrentHashMap<>();
    private final Map<EntityType, VanillaRegistry.EntitySpawner> entity2Spawner = new ConcurrentHashMap<>();
    private final Map<Class<Feature>, Feature> class2Feature = new ConcurrentHashMap<>();
    private final Map<Object, Random> randoms = Collections.synchronizedMap(new WeakHashMap<>());

    private VanillaReimplementationImpl(@NotNull ServerProcess process) {
        this.process = process;
    }

    /**
     * Creates a new instance of {@link VanillaReimplementationImpl} and hooks into the server process.
     *
     * @param process   the server process
     * @param predicate a predicate to determine which features to enable
     * @return the new instance
     */
    public static @NotNull VanillaReimplementationImpl hook(@NotNull ServerProcess process, Predicate<Feature> predicate) {
        Loading.start("Initialising");

        Loading.start("Initialising Minestom Resources...");
        MinestomUtils.initialize();
        Loading.finish();

        Loading.updater().progress(0.33);

        Loading.start("Instantiating vri");
        VanillaReimplementationImpl vri = new VanillaReimplementationImpl(process);
        Loading.finish();

        Loading.updater().progress(0.66);
        vri.INTERNAL_HOOK(predicate);
        Loading.updater().progress(1);

        Loading.finish();

        return vri;
    }

    // Vri Methods

    /**
     * @return the server process
     */
    public @NotNull ServerProcess process() {
        return process;
    }

    @Override
    public <T extends Feature> @NotNull T feature(Class<T> clazz) {
        //noinspection unchecked
        return (T) Objects.requireNonNull(class2Feature.get(clazz), () -> "Feature " + clazz + " has not loaded yet.");
    }


    /**
     * Creates an {@link VanillaRegistry.EntityContext} for the given type and position
     *
     * @param type     the type of the entity
     * @param position the position of the entity at spawn
     * @return the context
     */
    public @NotNull VanillaRegistry.EntityContext entityContext(EntityType type, Point position) {
        return new EntityContextImpl(type, Pos.fromPoint(position));
    }

    /**
     * Creates an {@link VanillaRegistry.EntityContext} for the given type and position, with the
     * given tag values.
     *
     * @param type     the type of the entity
     * @param position the position of the entity at spawn
     * @return the context
     */
    public @NotNull VanillaRegistry.EntityContext entityContext(EntityType type, Point position,
                                                                @NotNull Consumer<TagWritable> tagWriter) {
        EntityContextImpl impl = new EntityContextImpl(type, Pos.fromPoint(position));
        tagWriter.accept(impl);
        return impl;
    }

    private record EntityContextImpl(@NotNull EntityType type, @NotNull Pos position,
                                     @NotNull TagHandler tagHandler) implements VanillaRegistry.EntityContext, Taggable {
        public EntityContextImpl(@NotNull EntityType type, @NotNull Pos position) {
            this(type, position, TagHandler.newHandler());
        }
    }

    /**
     * Creates a new vanilla entity, using the specified context, returning null if the entity type is not implemented.
     *
     * @param context the context
     * @return the new entity
     */
    public @Nullable Entity createEntity(@NotNull VanillaRegistry.EntityContext context) {
        // Get the spawner
        VanillaRegistry.EntitySpawner spawner = entity2Spawner.get(context.type());

        // Create the entity
        return spawner != null ? spawner.spawn(context) : null;
    }

    /**
     * Creates a new vanilla entity, using the specified context, returning a dummy entity if the entity type is not
     * implemented.
     *
     * @param context the context
     * @return the new entity
     */
    public @NotNull Entity createEntityOrDummy(@NotNull VanillaRegistry.EntityContext context) {
        Entity entity = createEntity(context);
        return entity != null ? entity : new DummyEntity(context.type());
    }

    private static class DummyEntity extends Entity {
        public DummyEntity(@NotNull EntityType type) {
            super(type);
        }
    }

    /**
     * Creates a vanilla instance.
     */
    public @NotNull Instance createInstance(@NotNull Key name, @NotNull DimensionType dimension) {
        RegistryKey<DimensionType> key = process().dimensionType().getKey(dimension);
        Objects.requireNonNull(key, "Dimension type " + dimension + " is not registered!");
        InstanceContainer instance = process().instance().createInstanceContainer(key);
        worlds.put(name, instance);

        // Anvil directory
        AnvilLoader loader = new AnvilLoader(name.value());
        instance.setChunkLoader(loader);
        instance.setChunkSupplier(LightingChunk::new);

        // Setup event
        SetupVanillaInstanceEvent event = new SetupVanillaInstanceEvent(instance);
        process().eventHandler().call(event);

        return instance;
    }

    @Override
    public @NotNull Instance getInstance(Key dimensionId) {
        return worlds.get(dimensionId);
    }

    @Override
    public @NotNull Random random(@NotNull Object key) {
        return randoms.computeIfAbsent(key, k -> new Random(key.hashCode()));
    }

    final class VanillaRegistryImpl implements VanillaRegistry {
        @Override
        public void register(@NotNull EntityType type, @NotNull EntitySpawner supplier) {
            entity2Spawner.put(type, supplier);
        }
    }

    private void INTERNAL_HOOK(Predicate<Feature> predicate) {
        // Create the registry
        VanillaRegistry registry = new VanillaRegistryImpl();

        // Hook this core library
        Loading.start("Hooking Core Library");
        hookCoreLibrary();
        Loading.finish();

        // Load all the features and hook them
        Loading.start("Loading features from classpath");
        Set<Feature> features = ServiceLoader.load(Feature.class)
                .stream()
                .map(ServiceLoader.Provider::get)
                .collect(Collectors.toUnmodifiableSet());
        Loading.finish();

        Loading.start("Validating dependencies");
        for (Feature feature : features) {
            try {
                for (Class<? extends Feature> dependency : feature.dependencies()) {
                    Objects.requireNonNull(dependency, "Dependency cannot be null!");
                }
            } catch (Exception e) {
                Logger.error("Failed to load features! Does one of your features have a missing dependency feature?", e);
                throw new RuntimeException(e);
            }
        }
        Loading.finish();

        Loading.start("Sorting features by dependencies");
        List<Feature> sortedByDependencies = DependencySorting.sort(features);
        Loading.finish();

        for (Feature feature : sortedByDependencies) {
            if (!predicate.test(feature)) {
                Logger.info("Skipping feature %s...", feature.key());
                continue;
            }

            try {
                instructHook(feature, registry);
                //noinspection unchecked
                class2Feature.put((Class<Feature>) feature.getClass(), feature);
            } catch (Exception e) {
                Logger.error("Failed to load feature: " + feature.key(), e);
                throw new RuntimeException(e);
            }
        }
    }

    private void instructHook(Feature feature, VanillaRegistry registry) {
        try {
            Loading.start("" + feature.key());
            Feature.HookContext context = new HookContextImpl(this, registry, Loading.updater());
            feature.hook(context);
        } catch (Exception e) {
            Logger.error(e, "Failed to load feature: %s%n", feature.key());
            throw new RuntimeException(e);
        } finally {
            Loading.finish();
        }
    }

    private record HookContextImpl(VanillaReimplementation vri,
                                       VanillaRegistry registry,
                                       StatusUpdater status) implements Feature.HookContext {
    }

    private void hookCoreLibrary() {
        VanillaDimensionTypes.registerAll(process().dimensionType());
    }
}


================================================
FILE: core/src/main/java/net/minestom/vanilla/dimensions/VanillaDimensionTypes.java
================================================
package net.minestom.vanilla.dimensions;

import net.kyori.adventure.key.Key;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.world.DimensionType;

import java.util.Map;

public class VanillaDimensionTypes {

    public static final DimensionType OVERWORLD
Download .txt
gitextract_r6lz745n/

├── .github/
│   └── CONTRIBUTING.md
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── block-update-system/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           ├── BlockUpdateFeature.java
│                           ├── blockupdatesystem/
│                           │   ├── BlockUpdatable.java
│                           │   ├── BlockUpdateInfo.java
│                           │   └── BlockUpdateManager.java
│                           └── randomticksystem/
│                               ├── RandomTickManager.java
│                               └── RandomTickable.java
├── blocks/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── blocks/
│                               ├── VanillaBlockBehaviour.java
│                               ├── VanillaBlockLoot.java
│                               ├── VanillaBlocks.java
│                               ├── VanillaBlocksFeature.java
│                               └── behaviours/
│                                   ├── BedBlockBehaviour.java
│                                   ├── CakeBlockBehaviour.java
│                                   ├── ChestBlockBehaviour.java
│                                   ├── ConcretePowderBlockBehaviour.java
│                                   ├── EndPortalBlockBehaviour.java
│                                   ├── EnderChestBlockBehaviour.java
│                                   ├── FireBlockBehaviour.java
│                                   ├── GravityBlockBehaviour.java
│                                   ├── InventoryBlockBehaviour.java
│                                   ├── JukeboxBlockBehaviour.java
│                                   ├── NetherPortalBlockBehaviour.java
│                                   ├── TNTBlockBehaviour.java
│                                   ├── TrappedChestBlockBehaviour.java
│                                   ├── chestlike/
│                                   │   ├── BlockInventory.java
│                                   │   ├── BlockItems.java
│                                   │   └── DoubleChestInventory.java
│                                   ├── oxidisable/
│                                   │   ├── OxidatableBlockBehaviour.java
│                                   │   ├── OxidatedBlockBehaviour.java
│                                   │   ├── OxygenSensitive.java
│                                   │   ├── WaxableBlockBehaviour.java
│                                   │   └── WaxedBlockBehaviour.java
│                                   └── recipe/
│                                       ├── BlastingFurnaceBehaviour.java
│                                       ├── CampfireBehaviour.java
│                                       ├── CraftingTableBehaviour.java
│                                       ├── FurnaceBehaviour.java
│                                       ├── SmithingTableBehaviour.java
│                                       ├── SmokerBehaviour.java
│                                       └── StonecutterBehaviour.java
├── build.gradle.kts
├── commands/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── commands/
│                               ├── DifficultyCommand.java
│                               ├── ForceloadCommand.java
│                               ├── GamemodeCommand.java
│                               ├── HelpCommand.java
│                               ├── MeCommand.java
│                               ├── SaveAllCommand.java
│                               ├── StopCommand.java
│                               ├── VanillaCommands.java
│                               └── VanillaCommandsFeature.java
├── core/
│   ├── build.gradle.kts
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── net/
│       │   │       └── minestom/
│       │   │           └── vanilla/
│       │   │               ├── VanillaRegistry.java
│       │   │               ├── VanillaReimplementation.java
│       │   │               ├── VanillaReimplementationImpl.java
│       │   │               ├── dimensions/
│       │   │               │   └── VanillaDimensionTypes.java
│       │   │               ├── events/
│       │   │               │   ├── BlastingFurnaceTickEvent.java
│       │   │               │   ├── FurnaceTickEvent.java
│       │   │               │   └── SmokerTickEvent.java
│       │   │               ├── files/
│       │   │               │   ├── ByteArray.java
│       │   │               │   ├── CacheFileSystem.java
│       │   │               │   ├── DynamicFileSystem.java
│       │   │               │   ├── FileSystem.java
│       │   │               │   ├── FileSystemImpl.java
│       │   │               │   ├── FileSystemMappers.java
│       │   │               │   ├── FileSystemUtil.java
│       │   │               │   ├── LazyFileSystem.java
│       │   │               │   ├── MappedFileSystem.java
│       │   │               │   └── PathFileSystem.java
│       │   │               ├── instance/
│       │   │               │   ├── SetupVanillaInstanceEvent.java
│       │   │               │   └── VanillaExplosion.java
│       │   │               ├── inventory/
│       │   │               │   └── InventoryManipulation.java
│       │   │               ├── logging/
│       │   │               │   ├── Color.java
│       │   │               │   ├── Level.java
│       │   │               │   ├── Loading.java
│       │   │               │   ├── LoadingBar.java
│       │   │               │   ├── LoadingImpl.java
│       │   │               │   ├── Logger.java
│       │   │               │   ├── LoggerImpl.java
│       │   │               │   ├── LoggingLoadingBar.java
│       │   │               │   ├── SLF4JCompatibilityLayer.java
│       │   │               │   ├── SLF4JServiceProvider.java
│       │   │               │   └── StatusUpdater.java
│       │   │               ├── system/
│       │   │               │   ├── EnderChestSystem.java
│       │   │               │   ├── NetherPortal.java
│       │   │               │   ├── RayFastManager.java
│       │   │               │   ├── ServerProperties.java
│       │   │               │   └── nether/
│       │   │               │       ├── EntityEnterNetherPortalEvent.java
│       │   │               │       ├── NetherPortalTeleportEvent.java
│       │   │               │       └── NetherPortalUpdateEvent.java
│       │   │               ├── tag/
│       │   │               │   └── Tags.java
│       │   │               └── utils/
│       │   │                   ├── DependencySorting.java
│       │   │                   ├── JavaUtils.java
│       │   │                   ├── MathUtils.java
│       │   │                   ├── MinestomUtils.java
│       │   │                   └── ZipUtils.java
│       │   └── resources/
│       │       └── META-INF/
│       │           └── services/
│       │               └── org.tinylog.writers.Writer
│       └── test/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── files/
│                               └── FileSystemTests.java
├── crafting/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── crafting/
│                               ├── CraftingFeature.java
│                               ├── CraftingRecipes.java
│                               └── Recipe.java
├── datapack/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── datapack/
│                               └── Datapacks.java
├── datapack-loading/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── datapack/
│                               ├── Datapack.java
│                               ├── DatapackLoader.java
│                               ├── DatapackLoadingFeature.java
│                               ├── DatapackUtils.java
│                               ├── advancement/
│                               │   └── Advancement.java
│                               ├── dimension/
│                               │   └── DimensionType.java
│                               ├── json/
│                               │   ├── JsonUtils.java
│                               │   ├── ListLike.java
│                               │   └── Optional.java
│                               ├── loot/
│                               │   ├── LootTable.java
│                               │   ├── NBTPath.java
│                               │   ├── NBTPathImpl.java
│                               │   ├── context/
│                               │   │   ├── ContextGroups.java
│                               │   │   ├── LootContext.java
│                               │   │   ├── MappedTraitImpl.java
│                               │   │   ├── TraitImpl.java
│                               │   │   ├── Traits.java
│                               │   │   └── Util.java
│                               │   └── function/
│                               │       ├── InBuiltLootFunctions.java
│                               │       ├── InBuiltPredicates.java
│                               │       ├── LootFunction.java
│                               │       └── Predicate.java
│                               ├── nbt/
│                               │   └── NBTUtils.java
│                               ├── number/
│                               │   ├── DoubleNumberProviders.java
│                               │   ├── IntNumberProviders.java
│                               │   └── NumberProvider.java
│                               ├── recipe/
│                               │   └── Recipe.java
│                               ├── tags/
│                               │   ├── ConditionsFor.java
│                               │   └── Tag.java
│                               ├── trims/
│                               │   ├── TrimMaterial.java
│                               │   └── TrimPattern.java
│                               └── worldgen/
│                                   ├── Biome.java
│                                   ├── BlockState.java
│                                   ├── Carver.java
│                                   ├── DensityFunction.java
│                                   ├── DensityFunctions.java
│                                   ├── FloatProvider.java
│                                   ├── HeightProvider.java
│                                   ├── LazyLoadedDensityFunction.java
│                                   ├── NoiseSettings.java
│                                   ├── Structure.java
│                                   ├── VerticalAnchor.java
│                                   ├── WorldgenContext.java
│                                   ├── WorldgenRegistries.java
│                                   ├── biome/
│                                   │   ├── BiomeSource.java
│                                   │   ├── BiomeSources.java
│                                   │   └── Climate.java
│                                   ├── math/
│                                   │   ├── CubicSpline.java
│                                   │   ├── NumberFunction.java
│                                   │   └── SplineInterpolator.java
│                                   ├── noise/
│                                   │   ├── BlendedNoise.java
│                                   │   ├── ImprovedNoise.java
│                                   │   ├── LazyLoadedNoise.java
│                                   │   ├── Noise.java
│                                   │   ├── NormalNoise.java
│                                   │   ├── PerlinNoise.java
│                                   │   └── SimplexNoise.java
│                                   ├── random/
│                                   │   ├── LegacyRandom.java
│                                   │   ├── MarsagliaPolarGaussian.java
│                                   │   ├── WorldgenRandom.java
│                                   │   ├── XoroshiroPositionalRandom.java
│                                   │   └── XoroshiroRandom.java
│                                   ├── storage/
│                                   │   ├── DoubleStorage.java
│                                   │   ├── DoubleStorageCache.java
│                                   │   ├── DoubleStorageCache2d.java
│                                   │   └── DoubleStorageThreadLocalImpl.java
│                                   └── util/
│                                       └── Util.java
├── datapack-tests/
│   ├── build.gradle.kts
│   └── src/
│       └── test/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── datapack/
│                               ├── loot/
│                               │   ├── LootTableTestData.java
│                               │   └── LootTableTests.java
│                               └── worldgen/
│                                   ├── DF.java
│                                   ├── DFVisualizer.java
│                                   ├── DensityFunctionTests.java
│                                   ├── NoiseTests.java
│                                   └── RandomTests.java
├── entities/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── entities/
│                               ├── FallingBlockEntity.java
│                               ├── MinestomEntitiesFeature.java
│                               └── PrimedTNTEntity.java
├── entity-meta/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── entitymeta/
│                               └── EntityTags.java
├── fluid-simulation/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── github/
│                       └── togar2/
│                           └── fluids/
│                               ├── EmptyFluid.java
│                               ├── FlowableFluid.java
│                               ├── Fluid.java
│                               ├── FluidPlacementRule.java
│                               ├── FluidSimulationFeature.java
│                               ├── MinestomFluids.java
│                               ├── WaterBlockBreakEvent.java
│                               └── WaterFluid.java
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── instance-meta/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── instancemeta/
│                               ├── InstanceMetaFeature.java
│                               └── tickets/
│                                   ├── TicketManager.java
│                                   └── TicketUtils.java
├── item-placeables/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── itemplaceables/
│                               └── ItemPlaceablesFeature.java
├── items/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── items/
│                               ├── FlintAndSteelHandler.java
│                               ├── ItemManager.java
│                               ├── ItemsFeature.java
│                               ├── VanillaItemHandler.java
│                               └── VanillaItems.java
├── jitpack.yml
├── loot-table/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── loot/
│                               ├── BlockExperience.java
│                               ├── LootContext.java
│                               ├── LootEntry.java
│                               ├── LootFeature.java
│                               ├── LootFunction.java
│                               ├── LootGenerator.java
│                               ├── LootNBT.java
│                               ├── LootNumber.java
│                               ├── LootPool.java
│                               ├── LootPredicate.java
│                               ├── LootScore.java
│                               ├── LootTable.java
│                               └── util/
│                                   ├── EnchantmentUtils.java
│                                   ├── ListOperation.java
│                                   ├── LootNumberRange.java
│                                   ├── RelevantEntity.java
│                                   ├── RelevantTarget.java
│                                   ├── nbt/
│                                   │   ├── NBTPath.java
│                                   │   ├── NBTReference.java
│                                   │   └── NBTUtils.java
│                                   └── predicate/
│                                       ├── DamageSourcePredicate.java
│                                       ├── EntityPredicate.java
│                                       ├── ItemPredicate.java
│                                       └── LocationPredicate.java
├── mojang-data/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── github/
│                       └── pesto/
│                           ├── MojangAssets.java
│                           └── MojangDataFeature.java
├── server/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── server/
│                               ├── VanillaDebug.java
│                               ├── VanillaEvents.java
│                               └── VanillaServer.java
├── settings.gradle.kts
├── survival/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── minestom/
│                       └── vanilla/
│                           └── survival/
│                               └── Survival.java
└── world-generation/
    ├── build.gradle.kts
    └── src/
        └── main/
            └── java/
                └── net/
                    └── minestom/
                        └── vanilla/
                            └── generation/
                                ├── Aquifer.java
                                ├── NoiseChunk.java
                                ├── NoiseChunkGenerator.java
                                ├── RandomState.java
                                ├── SurfaceContext.java
                                ├── SurfaceSystem.java
                                ├── VanillaTestGenerator.java
                                ├── VanillaWorldGenerationFeature.java
                                └── VanillaWorldgen.java
Download .txt
SYMBOL INDEX (2384 symbols across 223 files)

FILE: block-update-system/src/main/java/net/minestom/vanilla/BlockUpdateFeature.java
  class BlockUpdateFeature (line 10) | public class BlockUpdateFeature implements VanillaReimplementation.Featu...
    method hook (line 11) | @Override
    method key (line 22) | @Override

FILE: block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdatable.java
  type BlockUpdatable (line 7) | public interface BlockUpdatable {
    method blockUpdate (line 13) | void blockUpdate(@NotNull Instance instance, @NotNull Point pos, @NotN...

FILE: block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdateInfo.java
  type BlockUpdateInfo (line 3) | public interface BlockUpdateInfo {
    method DESTROY_BLOCK (line 5) | static DestroyBlock DESTROY_BLOCK() {
    method PLACE_BLOCK (line 9) | static PlaceBlock PLACE_BLOCK() {
    method CHUNK_LOAD (line 13) | static ChunkLoad CHUNK_LOAD() {
    method MOVE_BLOCK (line 17) | static MoveBlock MOVE_BLOCK() {

FILE: block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdateManager.java
  class BlockUpdateManager (line 28) | public class BlockUpdateManager {
    method registerUpdatable (line 36) | public static void registerUpdatable(short stateId, @NotNull BlockUpda...
    method init (line 42) | public static void init(@NotNull VanillaReimplementation.Feature.HookC...
    method instanceTick (line 81) | private static void instanceTick(InstanceTickEvent event) {
    method from (line 86) | public static @NotNull BlockUpdateManager from(@NotNull Instance insta...
    method BlockUpdateManager (line 93) | public BlockUpdateManager(@NotNull BlockUpdateManager.UpdateHandler up...
    method BlockUpdateManager (line 97) | private BlockUpdateManager(@NotNull Instance instance) {
    type UpdateHandler (line 105) | public interface UpdateHandler {
      method update (line 106) | void update(@NotNull Point pos, @NotNull BlockUpdateInfo info);
    method scheduleNeighborsUpdate (line 114) | public void scheduleNeighborsUpdate(Point pos, BlockUpdateInfo info) {
    method tick (line 120) | private void tick(int duration) {
    method updateNeighbors (line 124) | private void updateNeighbors(int duration) {

FILE: block-update-system/src/main/java/net/minestom/vanilla/randomticksystem/RandomTickManager.java
  class RandomTickManager (line 19) | public class RandomTickManager {
    method RandomTickManager (line 28) | private RandomTickManager(VanillaReimplementation vri) {
    method create (line 32) | public static @NotNull RandomTickManager create(@NotNull VanillaReimpl...
    method init (line 36) | public static void init(VanillaReimplementation.Feature.@NotNull HookC...
    method registerRandomTickable (line 44) | public static void registerRandomTickable(short stateId, RandomTickabl...
    method handleInstanceTick (line 50) | private void handleInstanceTick(InstanceTickEvent event, int randomTic...
    method randomTickSection (line 66) | private void randomTickSection(Random random, Instance instance, Chunk...

FILE: block-update-system/src/main/java/net/minestom/vanilla/randomticksystem/RandomTickable.java
  type RandomTickable (line 8) | public interface RandomTickable {
    method randomTick (line 10) | void randomTick(@NotNull RandomTick randomTick);
    type RandomTick (line 12) | interface RandomTick {
      method instance (line 13) | @NotNull Instance instance();
      method position (line 14) | @NotNull Point position();
      method block (line 15) | @NotNull Block block();

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlockBehaviour.java
  class VanillaBlockBehaviour (line 16) | public abstract class VanillaBlockBehaviour implements BlockHandler {
    method VanillaBlockBehaviour (line 22) | protected VanillaBlockBehaviour(@NotNull VanillaBlocks.BlockContext co...
    method onPlace (line 32) | @Override
    method onPlace (line 37) | public void onPlace(@NotNull VanillaPlacement placement) {
    method getKey (line 40) | @Override
    type VanillaPlacement (line 45) | public interface VanillaPlacement {
      method blockToPlace (line 50) | @NotNull Block blockToPlace();
      method instance (line 55) | @NotNull Instance instance();
      method position (line 60) | @NotNull Point position();
      method blockToPlace (line 67) | void blockToPlace(@NotNull Block newBlock);
      type HasPlayer (line 69) | interface HasPlayer {
        method player (line 70) | @NotNull Player player();

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlockLoot.java
  method spawnLoot (line 32) | public void spawnLoot(@NotNull PlayerBlockBreakEvent event) {
  method getLoot (line 58) | public List<ItemStack> getLoot(LootTable lootTable, LootContext context) {
  method getLoot (line 62) | public List<ItemStack> getLoot(LootTable lootTable, LootContext context,...
  method generateLootItems (line 68) | private void generateLootItems(LootTable lootTable, LootContext context,...
  method get (line 146) | @Override
  method fails (line 152) | private static boolean fails(@Nullable List<Predicate> predicates, LootC...
  method addEntries (line 162) | private void addEntries(LootContext context, LootTable.Pool.Entry entry,...

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlocks.java
  type VanillaBlocks (line 32) | public enum VanillaBlocks {
    method VanillaBlocks (line 168) | VanillaBlocks(@NotNull Block minestomBlock, @NotNull Context2Handler c...
    type Context2Handler (line 179) | interface Context2Handler {
      method apply (line 180) | @NotNull VanillaBlockBehaviour apply(@NotNull BlockContext context);
    type BlockContext (line 186) | public interface BlockContext {
      method stateId (line 187) | short stateId();
      method vri (line 189) | @NotNull VanillaReimplementation vri();
    method create (line 198) | public @NotNull VanillaBlockBehaviour create(@NotNull BlockContext con...
    method registerAll (line 208) | public static void registerAll(@NotNull VanillaReimplementation vri) {
    method registerEvents (line 253) | private static void registerEvents(EventNode<Event> node, Short2Object...
    method blockToPlace (line 273) | @Override
    method instance (line 278) | @Override
    method position (line 283) | @Override
    method blockToPlace (line 288) | @Override
    method player (line 293) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlocksFeature.java
  class VanillaBlocksFeature (line 16) | public class VanillaBlocksFeature implements VanillaReimplementation.Fea...
    method hook (line 18) | @Override
    method blockToPlace (line 40) | @Override
    method instance (line 45) | @Override
    method position (line 50) | @Override
    method blockToPlace (line 55) | @Override
    method key (line 62) | @Override
    method dependencies (line 67) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/BedBlockBehaviour.java
  class BedBlockBehaviour (line 20) | @SuppressWarnings("UnstableApiUsage")
    method BedBlockBehaviour (line 22) | public BedBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
    method onPlace (line 32) | @Override
    method isReplaceable (line 61) | private boolean isReplaceable(Block blockAtPosition) {
    method placeBed (line 65) | private Block placeBed(Instance instance, Block bedBlock, Point headPo...
    method onInteract (line 74) | @Override
    method onDestroy (line 119) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/CakeBlockBehaviour.java
  class CakeBlockBehaviour (line 18) | public class CakeBlockBehaviour extends VanillaBlockBehaviour {
    method CakeBlockBehaviour (line 41) | public CakeBlockBehaviour(VanillaBlocks.@NotNull BlockContext context) {
    method onInteract (line 45) | @Override
    method onDestroy (line 78) | @Override
    method tryDropCandle (line 87) | private void tryDropCandle(Block block, Instance instance, Point point) {

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/ChestBlockBehaviour.java
  class ChestBlockBehaviour (line 8) | public class ChestBlockBehaviour extends InventoryBlockBehaviour {
    method ChestBlockBehaviour (line 9) | public ChestBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
    method dropContentsOnDestroy (line 13) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/ConcretePowderBlockBehaviour.java
  class ConcretePowderBlockBehaviour (line 11) | public class ConcretePowderBlockBehaviour extends GravityBlockBehaviour {
    method ConcretePowderBlockBehaviour (line 14) | public ConcretePowderBlockBehaviour(@NotNull VanillaBlocks.BlockContex...
    method onPlace (line 19) | @Override
    method tick (line 25) | @Override
    method tryConvert (line 30) | private void tryConvert(Instance instance, Point blockPosition) {

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/EndPortalBlockBehaviour.java
  class EndPortalBlockBehaviour (line 17) | public class EndPortalBlockBehaviour extends VanillaBlockBehaviour {
    method EndPortalBlockBehaviour (line 18) | public EndPortalBlockBehaviour(@NotNull VanillaBlocks.BlockContext con...
    method onTouch (line 27) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/EnderChestBlockBehaviour.java
  class EnderChestBlockBehaviour (line 15) | public class EnderChestBlockBehaviour extends InventoryBlockBehaviour {
    method EnderChestBlockBehaviour (line 16) | public EnderChestBlockBehaviour(@NotNull VanillaBlocks.BlockContext co...
    method dropContentsOnDestroy (line 20) | @Override
    method getAllItems (line 25) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/FireBlockBehaviour.java
  class FireBlockBehaviour (line 14) | public class FireBlockBehaviour extends VanillaBlockBehaviour {
    method FireBlockBehaviour (line 15) | public FireBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
    method onTouch (line 24) | @Override
    method checkForPortal (line 40) | public void checkForPortal(Instance instance, Point pos, Block block) {
    method onPlace (line 52) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/GravityBlockBehaviour.java
  class GravityBlockBehaviour (line 18) | public class GravityBlockBehaviour extends VanillaBlockBehaviour impleme...
    method GravityBlockBehaviour (line 19) | public GravityBlockBehaviour(@NotNull VanillaBlocks.BlockContext conte...
    method onPlace (line 23) | @Override
    method checkFall (line 41) | public boolean checkFall(Instance instance, Point position, Block bloc...
    method blockUpdate (line 63) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/InventoryBlockBehaviour.java
  class InventoryBlockBehaviour (line 32) | public abstract class InventoryBlockBehaviour extends VanillaBlockBehavi...
    method InventoryBlockBehaviour (line 39) | public InventoryBlockBehaviour(@NotNull VanillaBlocks.BlockContext con...
    method onPlace (line 45) | @Override
    method onDestroy (line 65) | @Override
    method onInteract (line 108) | @Override
    method dropContentsOnDestroy (line 129) | public abstract boolean dropContentsOnDestroy();
    method getItems (line 137) | protected @NotNull List<ItemStack> getItems(Block block) {
    method setItems (line 154) | protected Block setItems(Block block, List<ItemStack> items) {
    method getAllItems (line 168) | protected List<ItemStack> getAllItems(Instance instance, Point pos, Pl...

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/JukeboxBlockBehaviour.java
  class JukeboxBlockBehaviour (line 32) | public class JukeboxBlockBehaviour extends VanillaBlockBehaviour {
    method JukeboxBlockBehaviour (line 36) | public JukeboxBlockBehaviour(@NotNull VanillaBlocks.BlockContext conte...
    method onDestroy (line 40) | @Override
    method getDisc (line 46) | public @Nullable ItemStack getDisc(Block block) {
    method withDisc (line 50) | public @NotNull Block withDisc(Block block, @NotNull ItemStack disc) {
    method isNotMusicDisc (line 57) | private boolean isNotMusicDisc(ItemStack itemStack) {
    method onInteract (line 61) | @Override
    method isTickable (line 109) | @Override
    method tick (line 114) | public void tick(@NotNull Tick tick) {
    method stopPlayback (line 152) | private void stopPlayback(Instance instance, Point pos, Block block) {

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/NetherPortalBlockBehaviour.java
  class NetherPortalBlockBehaviour (line 27) | public class NetherPortalBlockBehaviour extends VanillaBlockBehaviour im...
    method NetherPortalBlockBehaviour (line 55) | public NetherPortalBlockBehaviour(@NotNull VanillaBlocks.BlockContext ...
    method onTouch (line 59) | @Override
    method updateTimeInPortal (line 99) | private long updateTimeInPortal(Instance instance, Point position, Ent...
    method attemptTeleport (line 135) | private void attemptTeleport(Instance instance, Entity touching, Block...
    method getCorrespondingNetherPortal (line 205) | private @Nullable NetherPortal getCorrespondingNetherPortal(Instance t...
    method calculateTargetPosition (line 210) | private Pos calculateTargetPosition(Entity touching, NetherPortal port...
    method teleport (line 254) | private void teleport(Instance instance, Entity touching, NetherPortal...
    method onDestroy (line 285) | @Override
    method getPortal (line 297) | private NetherPortal getPortal(Block block) {
    method breakPortalIfNoLongerValid (line 306) | private void breakPortalIfNoLongerValid(Instance instance, Point block...
    method setRelatedPortal (line 320) | public void setRelatedPortal(Instance instance, Point blockPosition, B...
    method blockUpdate (line 324) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/TNTBlockBehaviour.java
  class TNTBlockBehaviour (line 21) | public class TNTBlockBehaviour extends VanillaBlockBehaviour {
    method TNTBlockBehaviour (line 25) | public TNTBlockBehaviour(@NotNull VanillaBlocks.BlockContext context) {
    method onInteract (line 34) | @Override
    method spawnPrimedTNT (line 50) | private void spawnPrimedTNT(Instance instance, Point blockPosition, in...

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/TrappedChestBlockBehaviour.java
  class TrappedChestBlockBehaviour (line 8) | public class TrappedChestBlockBehaviour extends InventoryBlockBehaviour {
    method TrappedChestBlockBehaviour (line 11) | public TrappedChestBlockBehaviour(@NotNull VanillaBlocks.BlockContext ...
    method dropContentsOnDestroy (line 20) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/BlockInventory.java
  class BlockInventory (line 16) | public class BlockInventory extends Inventory {
    method BlockInventory (line 22) | private BlockInventory(Instance instance, Point pos, InventoryType inv...
    method from (line 37) | public static BlockInventory from(Instance instance, Point pos, Invent...
    method remove (line 52) | public static @NotNull List<ItemStack> remove(Instance instance, Point...
    method setItemStack (line 61) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/BlockItems.java
  class BlockItems (line 18) | public class BlockItems {
    method getTagForBlock (line 25) | private static Tag<List<ItemStack>> getTagForBlock(Block block) {
    method BlockItems (line 31) | private BlockItems(List<ItemStack> items) {
    method from (line 35) | public static BlockItems from(Block block) {
    method from (line 39) | public static BlockItems from(Block block, int requireStacks) {
    method requireStacks (line 47) | private void requireStacks(int requireStacks) {
    method itemStacks (line 56) | public @UnmodifiableView @NotNull List<ItemStack> itemStacks() {
    method size (line 60) | public int size() {
    method isEmpty (line 64) | public boolean isEmpty() {
    method isAir (line 68) | public boolean isAir() {
    method apply (line 72) | public Block apply(Block block) {
    method setItems (line 76) | public void setItems(List<ItemStack> itemStacks) {
    method get (line 81) | public ItemStack get(int index) {
    method set (line 85) | public void set(int index, ItemStack item) {

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/DoubleChestInventory.java
  class DoubleChestInventory (line 12) | public class DoubleChestInventory extends Inventory {
    method DoubleChestInventory (line 16) | public DoubleChestInventory(BlockInventory left, BlockInventory right,...
    method getItemStack (line 22) | @Override
    method setItemStack (line 30) | @Override
    method getItemStacks (line 39) | @Override
    method itemStacks (line 45) | public List<ItemStack> itemStacks() {

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxidatableBlockBehaviour.java
  class OxidatableBlockBehaviour (line 46) | public class OxidatableBlockBehaviour extends WaxableBlockBehaviour impl...
    method OxidatableBlockBehaviour (line 53) | public OxidatableBlockBehaviour(VanillaBlocks.@NotNull BlockContext co...
    method randomTick (line 60) | @Override
    method oxidisedLevel (line 120) | @Override
    method onInteract (line 125) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxidatedBlockBehaviour.java
  class OxidatedBlockBehaviour (line 7) | public abstract class OxidatedBlockBehaviour extends WaxableBlockBehavio...
    method OxidatedBlockBehaviour (line 11) | public OxidatedBlockBehaviour(VanillaBlocks.@NotNull BlockContext cont...
    method oxidisedLevel (line 16) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxygenSensitive.java
  type OxygenSensitive (line 3) | public interface OxygenSensitive {
    method oxidisedLevel (line 4) | int oxidisedLevel();

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/WaxableBlockBehaviour.java
  class WaxableBlockBehaviour (line 15) | public abstract class WaxableBlockBehaviour extends VanillaBlockBehaviour {
    method WaxableBlockBehaviour (line 17) | protected WaxableBlockBehaviour(VanillaBlocks.@NotNull BlockContext co...
    method onInteract (line 22) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/WaxedBlockBehaviour.java
  class WaxedBlockBehaviour (line 14) | public class WaxedBlockBehaviour extends OxidatedBlockBehaviour {
    method WaxedBlockBehaviour (line 17) | public WaxedBlockBehaviour(VanillaBlocks.@NotNull BlockContext context...
    method onInteract (line 22) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/BlastingFurnaceBehaviour.java
  class BlastingFurnaceBehaviour (line 17) | public class BlastingFurnaceBehaviour extends InventoryBlockBehaviour {
    method BlastingFurnaceBehaviour (line 18) | public BlastingFurnaceBehaviour(VanillaBlocks.@NotNull BlockContext co...
    method onInteract (line 22) | @Override
    method dropContentsOnDestroy (line 32) | @Override
    method isTickable (line 37) | @Override
    method tick (line 42) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/CampfireBehaviour.java
  class CampfireBehaviour (line 26) | public class CampfireBehaviour extends VanillaBlockBehaviour {
    method CampfireBehaviour (line 32) | public CampfireBehaviour(VanillaBlocks.@NotNull BlockContext context) {
    method getBlockItems (line 37) | public BlockItems getBlockItems(Block block) {
    method withCookingProgress (line 41) | public @NotNull Block withCookingProgress(Block block, int slotIndex, ...
    method appendItem (line 51) | public int appendItem(BlockItems items, @NotNull Material material) {
    method onInteract (line 65) | @Override
    method onDestroy (line 96) | @Override
    method tick (line 124) | @Override
    method getBlockEntityTags (line 168) | @Override
    method isTickable (line 173) | @Override
    method endCampfireCookingProgress (line 178) | private void endCampfireCookingProgress(Instance instance, Point pos, ...
    method dropItem (line 189) | private void dropItem(Instance instance, Point pos, ItemStack item) {
    method findFirstFreeSlot (line 195) | private OptionalInt findFirstFreeSlot(List<ItemStack> items) {
    method getRecipeResult (line 199) | private Material getRecipeResult(Recipe recipe) {
    method getRecipeInput (line 207) | private Material getRecipeInput(Recipe recipe) {
    method getMaterialFromSlotDisplay (line 215) | private Material getMaterialFromSlotDisplay(SlotDisplay slotDisplay) {
    method findCampfireCookingRecipe (line 223) | private Optional<Recipe> findCampfireCookingRecipe(ItemStack input) {

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/CraftingTableBehaviour.java
  class CraftingTableBehaviour (line 14) | public class CraftingTableBehaviour extends VanillaBlockBehaviour {
    method CraftingTableBehaviour (line 15) | public CraftingTableBehaviour(VanillaBlocks.@NotNull BlockContext cont...
    method onInteract (line 19) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/FurnaceBehaviour.java
  class FurnaceBehaviour (line 17) | public class FurnaceBehaviour extends InventoryBlockBehaviour {
    method FurnaceBehaviour (line 18) | public FurnaceBehaviour(VanillaBlocks.@NotNull BlockContext context) {
    method onInteract (line 22) | @Override
    method dropContentsOnDestroy (line 32) | @Override
    method isTickable (line 37) | @Override
    method tick (line 42) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/SmithingTableBehaviour.java
  class SmithingTableBehaviour (line 13) | public class SmithingTableBehaviour extends VanillaBlockBehaviour {
    method SmithingTableBehaviour (line 14) | public SmithingTableBehaviour(VanillaBlocks.@NotNull BlockContext cont...
    method onInteract (line 19) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/SmokerBehaviour.java
  class SmokerBehaviour (line 17) | public class SmokerBehaviour extends InventoryBlockBehaviour {
    method SmokerBehaviour (line 18) | public SmokerBehaviour(VanillaBlocks.@NotNull BlockContext context) {
    method onInteract (line 22) | @Override
    method dropContentsOnDestroy (line 32) | @Override
    method isTickable (line 37) | @Override
    method tick (line 42) | @Override

FILE: blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/StonecutterBehaviour.java
  class StonecutterBehaviour (line 13) | public class StonecutterBehaviour extends VanillaBlockBehaviour {
    method StonecutterBehaviour (line 14) | public StonecutterBehaviour(VanillaBlocks.@NotNull BlockContext contex...
    method onInteract (line 20) | @Override

FILE: commands/src/main/java/net/minestom/vanilla/commands/DifficultyCommand.java
  class DifficultyCommand (line 16) | public class DifficultyCommand extends Command {
    method DifficultyCommand (line 17) | public DifficultyCommand() {
    method usage (line 32) | private void usage(CommandSender player, CommandContext arguments) {
    method execute (line 36) | private void execute(CommandSender player, CommandContext arguments) {
    method difficultyCallback (line 43) | private void difficultyCallback(@NotNull CommandSender sender, @NotNul...
    method isAllowed (line 47) | private boolean isAllowed(CommandSender player, String commandName) {

FILE: commands/src/main/java/net/minestom/vanilla/commands/ForceloadCommand.java
  class ForceloadCommand (line 27) | public class ForceloadCommand extends Command {
    method ForceloadCommand (line 29) | public ForceloadCommand() {
    method addForceLoad (line 61) | private void addForceLoad(Instance instance, int chunkX, int chunkZ) {
    method addForceLoad (line 65) | private void addForceLoad(Instance instance, long chunkIndex) {
    method removeForceLoad (line 70) | private void removeForceLoad(Instance instance, int chunkX, int chunkZ) {
    method removeForceLoad (line 74) | private void removeForceLoad(Instance instance, long chunkIndex) {
    method usageAddFrom (line 80) | private void usageAddFrom(CommandSender sender, CommandContext context) {
    method usageAddFromTo (line 97) | private void usageAddFromTo(CommandSender sender, CommandContext conte...
    method usageRemoveFrom (line 124) | private void usageRemoveFrom(CommandSender sender, CommandContext cont...
    method usageRemoveFromTo (line 142) | private void usageRemoveFromTo(CommandSender sender, CommandContext co...

FILE: commands/src/main/java/net/minestom/vanilla/commands/GamemodeCommand.java
  class GamemodeCommand (line 24) | public class GamemodeCommand extends Command {
    method GamemodeCommand (line 26) | public GamemodeCommand() {
    method executeOthers (line 86) | private void executeOthers(CommandSender sender, GameMode mode, List<E...
    method executeSelf (line 117) | private void executeSelf(Player sender, GameMode mode) {

FILE: commands/src/main/java/net/minestom/vanilla/commands/HelpCommand.java
  class HelpCommand (line 14) | public class HelpCommand extends Command {
    method HelpCommand (line 15) | public HelpCommand() {
    method execute (line 21) | private void execute(CommandSender sender, CommandContext context) {
    method compareCommands (line 35) | private int compareCommands(VanillaCommands a, VanillaCommands b) {

FILE: commands/src/main/java/net/minestom/vanilla/commands/MeCommand.java
  class MeCommand (line 16) | public class MeCommand extends Command {
    method MeCommand (line 17) | public MeCommand() {
    method usage (line 27) | private void usage(CommandSender player, CommandContext arguments) {
    method execute (line 31) | private void execute(CommandSender sender, CommandContext arguments) {
    method isAllowed (line 53) | @SuppressWarnings("unused")

FILE: commands/src/main/java/net/minestom/vanilla/commands/SaveAllCommand.java
  class SaveAllCommand (line 12) | public class SaveAllCommand extends Command {
    method SaveAllCommand (line 13) | public SaveAllCommand() {
    method condition (line 19) | private boolean condition(CommandSender player, String commandName) {
    method execute (line 23) | private void execute(CommandSender player, CommandContext arguments) {

FILE: commands/src/main/java/net/minestom/vanilla/commands/StopCommand.java
  class StopCommand (line 11) | public class StopCommand extends Command {
    method StopCommand (line 12) | public StopCommand() {
    method condition (line 18) | private boolean condition(CommandSender player, String commandName) {
    method execute (line 22) | private void execute(CommandSender player, CommandContext arguments) {

FILE: commands/src/main/java/net/minestom/vanilla/commands/VanillaCommands.java
  type VanillaCommands (line 12) | public enum VanillaCommands {
    method VanillaCommands (line 25) | VanillaCommands(Supplier<Command> commandCreator) {
    method registerAll (line 34) | public static void registerAll(@NotNull CommandManager manager) {

FILE: commands/src/main/java/net/minestom/vanilla/commands/VanillaCommandsFeature.java
  class VanillaCommandsFeature (line 11) | public class VanillaCommandsFeature implements VanillaReimplementation.F...
    method hook (line 13) | @Override
    method key (line 18) | @Override
    class Logic (line 23) | private static class Logic {
      method Logic (line 24) | private Logic() {
      method hook (line 27) | private void hook(@NotNull VanillaReimplementation vri) {
    method dependencies (line 32) | @Override

FILE: core/src/main/java/net/minestom/vanilla/VanillaRegistry.java
  type VanillaRegistry (line 12) | public sealed interface VanillaRegistry permits VanillaReimplementationI...
    method register (line 20) | void register(@NotNull EntityType type, @NotNull EntitySpawner supplier);
    type EntitySpawner (line 22) | interface EntitySpawner {
      method spawn (line 23) | @NotNull Entity spawn(@NotNull VanillaRegistry.EntityContext context);
    type EntityContext (line 26) | interface EntityContext extends TagReadable {
      method type (line 27) | @NotNull EntityType type();
      method position (line 29) | @NotNull Pos position();

FILE: core/src/main/java/net/minestom/vanilla/VanillaReimplementation.java
  type VanillaReimplementation (line 21) | public interface VanillaReimplementation {
    method hook (line 29) | static @NotNull VanillaReimplementation hook(@NotNull ServerProcess pr...
    method hook (line 43) | static @NotNull VanillaReimplementation hook(@NotNull ServerProcess pr...
    method process (line 52) | @NotNull ServerProcess process();
    method feature (line 60) | <T extends Feature> @NotNull T feature(Class<T> clazz);
    method entityContext (line 69) | default @NotNull VanillaRegistry.EntityContext entityContext(EntityTyp...
    method entityContext (line 82) | @NotNull VanillaRegistry.EntityContext entityContext(EntityType type, ...
    method createEntity (line 91) | @Nullable Entity createEntity(@NotNull VanillaRegistry.EntityContext c...
    method createEntityOrDummy (line 100) | @NotNull Entity createEntityOrDummy(@NotNull VanillaRegistry.EntityCon...
    method createInstance (line 105) | @NotNull Instance createInstance(@NotNull Key namespace, @NotNull Dime...
    method getInstance (line 113) | @Nullable Instance getInstance(Key namespace);
    method random (line 124) | @NotNull Random random(@NotNull Object key);
    type Feature (line 129) | interface Feature extends DependencySorting.NamespaceDependent<Class<?...
      method hook (line 140) | @Deprecated
      method hook (line 152) | void hook(@NotNull HookContext context);
      type HookContext (line 154) | interface HookContext {
        method vri (line 155) | @NotNull VanillaReimplementation vri();
        method registry (line 156) | @NotNull VanillaRegistry registry();
        method status (line 157) | @NotNull StatusUpdater status();
      method dependencies (line 165) | default @NotNull Set<Class<? extends Feature>> dependencies() {
      method key (line 172) | @NotNull Key key();
      method identity (line 177) | default @NotNull Class<? extends Feature> identity() {

FILE: core/src/main/java/net/minestom/vanilla/VanillaReimplementationImpl.java
  class VanillaReimplementationImpl (line 34) | class VanillaReimplementationImpl implements VanillaReimplementation {
    method VanillaReimplementationImpl (line 42) | private VanillaReimplementationImpl(@NotNull ServerProcess process) {
    method hook (line 53) | public static @NotNull VanillaReimplementationImpl hook(@NotNull Serve...
    method process (line 80) | public @NotNull ServerProcess process() {
    method feature (line 84) | @Override
    method entityContext (line 98) | public @NotNull VanillaRegistry.EntityContext entityContext(EntityType...
    method entityContext (line 110) | public @NotNull VanillaRegistry.EntityContext entityContext(EntityType...
    method EntityContextImpl (line 119) | public EntityContextImpl(@NotNull EntityType type, @NotNull Pos positi...
    method createEntity (line 130) | public @Nullable Entity createEntity(@NotNull VanillaRegistry.EntityCo...
    method createEntityOrDummy (line 145) | public @NotNull Entity createEntityOrDummy(@NotNull VanillaRegistry.En...
    class DummyEntity (line 150) | private static class DummyEntity extends Entity {
      method DummyEntity (line 151) | public DummyEntity(@NotNull EntityType type) {
    method createInstance (line 159) | public @NotNull Instance createInstance(@NotNull Key name, @NotNull Di...
    method getInstance (line 177) | @Override
    method random (line 182) | @Override
    class VanillaRegistryImpl (line 187) | final class VanillaRegistryImpl implements VanillaRegistry {
      method register (line 188) | @Override
    method INTERNAL_HOOK (line 194) | private void INTERNAL_HOOK(Predicate<Feature> predicate) {
    method instructHook (line 245) | private void instructHook(Feature feature, VanillaRegistry registry) {
    method hookCoreLibrary (line 263) | private void hookCoreLibrary() {

FILE: core/src/main/java/net/minestom/vanilla/dimensions/VanillaDimensionTypes.java
  class VanillaDimensionTypes (line 9) | public class VanillaDimensionTypes {
    method values (line 14) | public static Map<DimensionType, Key> values() {
    method registerAll (line 20) | public static void registerAll(DynamicRegistry<DimensionType> registry) {

FILE: core/src/main/java/net/minestom/vanilla/files/ByteArray.java
  class ByteArray (line 11) | public class ByteArray {
    method ByteArray (line 15) | private ByteArray(byte[] b, boolean copy) {
    method wrap (line 19) | public static ByteArray wrap(byte[] bytes) {
    method copyOf (line 23) | public static ByteArray copyOf(byte[] bytes) {
    method array (line 27) | public byte[] array() {
    method size (line 31) | public int size() {
    method index (line 35) | public byte index(int i) {
    method toStream (line 41) | public InputStream toStream() {
    method toCharacterString (line 45) | public String toCharacterString() {
    method toCharacterString (line 49) | public String toCharacterString(Charset charset) {
    method deepCopy (line 53) | private byte[] deepCopy(byte[] source) {
    method equals (line 59) | @Override
    method hashCode (line 67) | @Override

FILE: core/src/main/java/net/minestom/vanilla/files/CacheFileSystem.java
  class CacheFileSystem (line 8) | class CacheFileSystem<F> implements FileSystemImpl<F> {
    method CacheFileSystem (line 15) | protected CacheFileSystem(FileSystem<F> original) {
    method folders (line 23) | @Override
    method files (line 28) | @Override
    method folder (line 33) | @Override
    method file (line 38) | @Override
    method toString (line 43) | @Override
    method cache (line 48) | @Override

FILE: core/src/main/java/net/minestom/vanilla/files/DynamicFileSystem.java
  class DynamicFileSystem (line 11) | public class DynamicFileSystem<F> implements FileSystemImpl<F> {
    method DynamicFileSystem (line 16) | protected DynamicFileSystem() {}
    method from (line 18) | static <F> FileSystem<F> from(FileSystemImpl<F> fileSystem) {
    method addFolder (line 31) | public DynamicFileSystem<F> addFolder(String directoryName) {
    method addFile (line 42) | public void addFile(String name, F contents) {
    method folders (line 54) | @Override
    method files (line 59) | @Override
    method folder (line 64) | @Override
    method file (line 70) | @Override
    method toString (line 75) | @Override
    method inMemory (line 80) | @Override

FILE: core/src/main/java/net/minestom/vanilla/files/FileSystem.java
  type FileSystem (line 11) | public interface FileSystem<F> extends FileSystemMappers {
    method folders (line 18) | Set<String> folders();
    method files (line 25) | Set<String> files();
    method folder (line 33) | FileSystem<F> folder(String path);
    method file (line 40) | F file(String path);
    method folder (line 42) | FileSystem<F> folder(@NotNull String... paths);
    method map (line 44) | <T> FileSystem<T> map(Function<F, T> mapper);
    method map (line 46) | <T> FileSystem<T> map(BiFunction<String, F, T> mapper);
    method cache (line 48) | FileSystem<F> cache();
    method lazy (line 50) | FileSystem<F> lazy();
    method inMemory (line 52) | FileSystem<F> inMemory();
    method empty (line 54) | static <T> FileSystem<T> empty() {
    method fromZipFile (line 59) | static FileSystem<ByteArray> fromZipFile(File file, Predicate<String> ...
    method hasFile (line 63) | default boolean hasFile(String file) {
    method hasFolder (line 67) | default boolean hasFolder(String path) {

FILE: core/src/main/java/net/minestom/vanilla/files/FileSystemImpl.java
  type FileSystemImpl (line 12) | interface FileSystemImpl<F> extends FileSystem<F> {
    method folder (line 14) | default FileSystem<F> folder(@NotNull String... paths) {
    method map (line 29) | default <T> FileSystem<T> map(Function<F, T> mapper) {
    method map (line 33) | default <T> FileSystem<T> map(BiFunction<String, F, T> mapper) {
    method cache (line 37) | default FileSystem<F> cache() {
    method lazy (line 41) | default FileSystem<F> lazy() {
    method inMemory (line 45) | default FileSystem<F> inMemory() {
    method toString (line 49) | static String toString(FileSystem<?> fs) {
    method toString (line 55) | static void toString(FileSystem<?> fs, Stream.Builder<String> builder,...

FILE: core/src/main/java/net/minestom/vanilla/files/FileSystemMappers.java
  type FileSystemMappers (line 8) | interface FileSystemMappers {

FILE: core/src/main/java/net/minestom/vanilla/files/FileSystemUtil.java
  class FileSystemUtil (line 16) | class FileSystemUtil {
    method toBytes (line 18) | static <I extends InputStream> FileSystem<ByteArray> toBytes(FileSyste...
    method toString (line 28) | static <I extends InputStream> FileSystem<String> toString(FileSystem<...
    method toJson (line 32) | static <T extends InputStream> FileSystem<JsonElement> toJson(FileSyst...
    method unzipIntoFileSystem (line 37) | static DynamicFileSystem<ByteArray> unzipIntoFileSystem(@NotNull File ...

FILE: core/src/main/java/net/minestom/vanilla/files/LazyFileSystem.java
  class LazyFileSystem (line 13) | public class LazyFileSystem<F> implements FileSystemImpl<F> {
    method LazyFileSystem (line 17) | protected LazyFileSystem(FileSystem<F> original) {
    method folders (line 22) | @Override
    method files (line 31) | @Override
    method folder (line 41) | @Override
    method file (line 47) | @Override
    method toString (line 52) | @Override
    method lazy (line 57) | @Override

FILE: core/src/main/java/net/minestom/vanilla/files/MappedFileSystem.java
  class MappedFileSystem (line 6) | class MappedFileSystem<F, T> implements FileSystemImpl<T> {
    method MappedFileSystem (line 11) | protected MappedFileSystem(FileSystem<F> original, BiFunction<String, ...
    method folders (line 16) | @Override
    method files (line 21) | @Override
    method folder (line 26) | @Override
    method file (line 31) | @Override
    method toString (line 36) | @Override

FILE: core/src/main/java/net/minestom/vanilla/files/PathFileSystem.java
  class PathFileSystem (line 10) | class PathFileSystem implements FileSystemImpl<ByteArray> {
    method PathFileSystem (line 13) | protected PathFileSystem(Path path) {
    method folders (line 17) | @Override
    method files (line 30) | @Override
    method folder (line 43) | @Override
    method file (line 48) | @Override
    method toString (line 57) | @Override

FILE: core/src/main/java/net/minestom/vanilla/instance/SetupVanillaInstanceEvent.java
  class SetupVanillaInstanceEvent (line 7) | public class SetupVanillaInstanceEvent implements InstanceEvent {
    method SetupVanillaInstanceEvent (line 11) | public SetupVanillaInstanceEvent(@NotNull Instance instance) {
    method getInstance (line 15) | @Override

FILE: core/src/main/java/net/minestom/vanilla/instance/VanillaExplosion.java
  class VanillaExplosion (line 23) | public class VanillaExplosion extends Explosion {
    method VanillaExplosion (line 38) | protected VanillaExplosion(Point center, float strength, boolean dropE...
    method builder (line 46) | public static Builder builder(Point center, float strength) {
    method prepare (line 50) | @Override
    method postSend (line 162) | @Override
    method affect (line 191) | private void affect(Entity e, final float damageRadius) {
    method calculateExposure (line 216) | private float calculateExposure(Entity e, final float damageRadius) {
    method getEntitiesAround (line 257) | private List<Entity> getEntitiesAround(Instance instance, double damag...
    method trigger (line 288) | public void trigger(Instance instance) {
    class Builder (line 292) | public static class Builder {
      method Builder (line 301) | protected Builder(Point center, float strength) {
      method dropEverything (line 306) | public Builder dropEverything(boolean dropEverything) {
      method isFlaming (line 311) | public Builder isFlaming(boolean isFlaming) {
      method destroyBlocks (line 316) | public Builder destroyBlocks(boolean dontDestroyBlocks) {
      method build (line 321) | public VanillaExplosion build() {

FILE: core/src/main/java/net/minestom/vanilla/inventory/InventoryManipulation.java
  class InventoryManipulation (line 11) | public class InventoryManipulation {
    method consumeItemIfNotCreative (line 12) | public static void consumeItemIfNotCreative(Player player, ItemStack i...
    method consumeItemIfNotCreative (line 25) | public static boolean consumeItemIfNotCreative(Player player, PlayerHa...
    method damageItemIfNotCreative (line 38) | public static void damageItemIfNotCreative(Player player, PlayerHand h...

FILE: core/src/main/java/net/minestom/vanilla/logging/Color.java
  type Color (line 3) | public enum Color {
    method Color (line 79) | Color(String code) {
    method toString (line 83) | @Override

FILE: core/src/main/java/net/minestom/vanilla/logging/Level.java
  type Level (line 3) | public enum Level {

FILE: core/src/main/java/net/minestom/vanilla/logging/Loading.java
  type Loading (line 3) | public interface Loading {
    method start (line 5) | static void start(String name) {
    method updater (line 8) | static StatusUpdater updater() {
    method finish (line 11) | static void finish() {
    method level (line 14) | static void level(Level level) {

FILE: core/src/main/java/net/minestom/vanilla/logging/LoadingBar.java
  type LoadingBar (line 3) | interface LoadingBar {
    method console (line 5) | static LoadingBar console(String initialMessage) {
    method logger (line 8) | static LoadingBar logger(String initialMessage, Logger logger) {
    method subTask (line 11) | LoadingBar subTask(String task);
    method updater (line 12) | StatusUpdater updater();
    method message (line 14) | String message();

FILE: core/src/main/java/net/minestom/vanilla/logging/LoadingImpl.java
  class LoadingImpl (line 6) | class LoadingImpl implements Loading {
    method LoadingImpl (line 14) | private LoadingImpl(@Nullable LoadingImpl parent, @Nullable LoadingBar...
    method waitTask (line 20) | public synchronized void waitTask(String name) {
    method finishTask (line 31) | public synchronized void finishTask() {
    method getUpdater (line 41) | public synchronized StatusUpdater getUpdater() {

FILE: core/src/main/java/net/minestom/vanilla/logging/Logger.java
  type Logger (line 3) | public interface Logger {
    method logger (line 4) | static Logger logger() {
    method debug (line 11) | static Logger debug() {
    method debug (line 14) | static Logger debug(String message, Object... args) {
    method debug (line 18) | static Logger debug(Throwable throwable, Object... args) {
    method setup (line 25) | static Logger setup() {
    method setup (line 28) | static Logger setup(String message, Object... args) {
    method setup (line 32) | static Logger setup(Throwable throwable, Object... args) {
    method info (line 39) | static Logger info() {
    method info (line 42) | static Logger info(String message, Object... args) {
    method info (line 46) | static Logger info(Throwable throwable, Object... args) {
    method warn (line 53) | static Logger warn() {
    method warn (line 56) | static Logger warn(String message, Object... args) {
    method warn (line 60) | static Logger warn(Throwable throwable, Object... args) {
    method error (line 67) | static Logger error() {
    method error (line 70) | static Logger error(String message, Object... args) {
    method error (line 74) | static Logger error(Throwable throwable, Object... args) {
    method level (line 83) | Logger level(Level level);
    method level (line 88) | Level level();
    method print (line 90) | Logger print(String message);
    method println (line 91) | default Logger println(String message) {
    method println (line 94) | default Logger println() {
    method printf (line 97) | Logger printf(String message, Object... args);
    method throwable (line 98) | Logger throwable(Throwable throwable, Object... args);
    method nextLine (line 104) | Logger nextLine();

FILE: core/src/main/java/net/minestom/vanilla/logging/LoggerImpl.java
  method write (line 23) | @Override
  method level (line 36) | @Override
  method consolePrint (line 42) | private void consolePrint(String str) {
  method newLine (line 48) | private void newLine() {
  method print (line 53) | @Override
  method printNonNewLine (line 78) | private void printNonNewLine(String message) {
  method preparePrefix (line 90) | private String preparePrefix() {
  method nextLine (line 106) | @Override
  method prepareLevelPrefix (line 115) | private String prepareLevelPrefix() {
  method printf (line 127) | @Override
  method throwable (line 132) | @Override
  method equals (line 143) | @Override

FILE: core/src/main/java/net/minestom/vanilla/logging/LoggingLoadingBar.java
  class LoggingLoadingBar (line 5) | class LoggingLoadingBar implements LoadingBar {
    method LoggingLoadingBar (line 15) | public LoggingLoadingBar(String initialMessage, Consumer<String> out) {
    method subTask (line 23) | @Override
    method updater (line 28) | public StatusUpdater updater() {
    method message (line 32) | @Override
    method renderThis (line 37) | private void renderThis() {
    method render (line 42) | private static void render(String message, double progress, Consumer<S...
    method accumulate (line 52) | @SuppressWarnings("UnnecessaryUnicodeEscape")
    class UpdaterImpl (line 77) | private class UpdaterImpl implements StatusUpdater {
      method progress (line 78) | @Override
      method message (line 86) | @Override
    class SubTaskLoadingBar (line 95) | public class SubTaskLoadingBar implements LoadingBar {
      method SubTaskLoadingBar (line 102) | public SubTaskLoadingBar(LoadingBar parent, String message, int dept...
      method subTask (line 110) | @Override
      method printIndent (line 115) | private void printIndent(LoadingBar bar) {
      method renderThis (line 124) | private void renderThis() {
      method updater (line 131) | @Override
      method message (line 136) | @Override
      class UpdaterImpl (line 141) | private class UpdaterImpl implements StatusUpdater {
        method progress (line 142) | @Override
        method message (line 150) | @Override

FILE: core/src/main/java/net/minestom/vanilla/logging/SLF4JCompatibilityLayer.java
  class SLF4JCompatibilityLayer (line 6) | class SLF4JCompatibilityLayer extends AbstractLogger implements org.slf4...
    method SLF4JCompatibilityLayer (line 9) | public SLF4JCompatibilityLayer(String name) {
    method getName (line 13) | @Override
    method isTraceEnabled (line 18) | @Override
    method isTraceEnabled (line 23) | @Override
    method isDebugEnabled (line 28) | @Override
    method isDebugEnabled (line 33) | @Override
    method isInfoEnabled (line 38) | @Override
    method isInfoEnabled (line 43) | @Override
    method isWarnEnabled (line 48) | @Override
    method isWarnEnabled (line 53) | @Override
    method isErrorEnabled (line 58) | @Override
    method isErrorEnabled (line 63) | @Override
    method getFullyQualifiedCallerName (line 68) | @Override
    method fromSlf4jLevel (line 73) | private Level fromSlf4jLevel(org.slf4j.event.Level level) {
    method handleNormalizedLoggingCall (line 83) | @Override

FILE: core/src/main/java/net/minestom/vanilla/logging/SLF4JServiceProvider.java
  class SLF4JServiceProvider (line 9) | public class SLF4JServiceProvider implements  org.slf4j.spi.SLF4JService...
    method SLF4JServiceProvider (line 11) | public SLF4JServiceProvider() {
    method getLoggerFactory (line 14) | @Override
    method getMarkerFactory (line 22) | @Override
    method getMDCAdapter (line 27) | @Override
    method getRequestedApiVersion (line 32) | @Override
    method initialize (line 37) | @Override

FILE: core/src/main/java/net/minestom/vanilla/logging/StatusUpdater.java
  type StatusUpdater (line 3) | public interface StatusUpdater {
    method progress (line 8) | void progress(double progress);
    method message (line 14) | void message(String message);

FILE: core/src/main/java/net/minestom/vanilla/system/EnderChestSystem.java
  class EnderChestSystem (line 12) | public class EnderChestSystem {
    method EnderChestSystem (line 18) | private EnderChestSystem() {
    method getItems (line 21) | public List<ItemStack> getItems(@NotNull Player player) {
    method getItems (line 25) | public @NotNull List<ItemStack> getItems(@NotNull UUID uuid) {
    method getInstance (line 29) | public static EnderChestSystem getInstance() {

FILE: core/src/main/java/net/minestom/vanilla/system/NetherPortal.java
  class NetherPortal (line 27) | @SuppressWarnings("UnstableApiUsage")
    method fromId (line 55) | public static @Nullable NetherPortal fromId(@Nullable Long id) {
    method NetherPortal (line 59) | public NetherPortal(Axis axis, Point frameBottomRightCorner, Point fra...
    method getAxis (line 73) | public Axis getAxis() {
    method getFrameBottomRightCorner (line 77) | public Point getFrameBottomRightCorner() {
    method getFrameTopLeftCorner (line 81) | public Point getFrameTopLeftCorner() {
    method getCenter (line 89) | public Vec getCenter() {
    method isStillValid (line 93) | public boolean isStillValid(Instance instance) {
    method breakFrame (line 97) | public void breakFrame(Instance instance) {
    method tryFillFrame (line 129) | public boolean tryFillFrame(Instance instance) {
    method replaceFrameContents (line 146) | private boolean replaceFrameContents(Instance instance, boolean checkP...
    method findPortalFrameFromFrameBlock (line 189) | public static NetherPortal findPortalFrameFromFrameBlock(Instance inst...
    method findPortalFrameFromFrameBlock (line 197) | private static NetherPortal findPortalFrameFromFrameBlock(Instance ins...
    method checkFrameIsObsidian (line 311) | private static boolean checkFrameIsObsidian(Instance instance, Axis ax...
    method checkInsideFrameForAir (line 375) | private static boolean checkInsideFrameForAir(Instance instance, int m...
    method unregister (line 399) | public void unregister(Instance instance) {
    method register (line 410) | public void register(Instance instance) {
    method generate (line 424) | public void generate(Instance instance) {
    method loadAround (line 444) | private CompletableFuture<Void> loadAround(Instance instance, Point co...
    method createFrame (line 459) | private void createFrame(Instance instance) {
    method computeWidth (line 505) | public int computeWidth() {
    method computeHeight (line 514) | public int computeHeight() {
    method id (line 520) | public long id() {
    type Axis (line 524) | public enum Axis {
      method Axis (line 531) | Axis(int xMultiplier, int zMultiplier) {
      method toString (line 537) | @Override

FILE: core/src/main/java/net/minestom/vanilla/system/RayFastManager.java
  class RayFastManager (line 7) | public class RayFastManager {
    method init (line 9) | @SuppressWarnings("UnstableApiUsage")

FILE: core/src/main/java/net/minestom/vanilla/system/ServerProperties.java
  class ServerProperties (line 10) | public class ServerProperties {
    method ServerProperties (line 18) | public ServerProperties(File source) throws IOException {
    method ServerProperties (line 29) | public ServerProperties(String source) throws IOException {
    method loadDefault (line 36) | private void loadDefault() throws IOException {
    method load (line 42) | public void load() throws IOException {
    method get (line 48) | public String get(String key) {
    method set (line 52) | public void set(String key, String value) {
    method save (line 56) | public void save() throws IOException {

FILE: core/src/main/java/net/minestom/vanilla/system/nether/EntityEnterNetherPortalEvent.java
  class EntityEnterNetherPortalEvent (line 15) | public class EntityEnterNetherPortalEvent implements Event, InstanceEven...
    method EntityEnterNetherPortalEvent (line 21) | public EntityEnterNetherPortalEvent(Entity entity, Point position, Net...
    method getEntity (line 27) | @Override
    method getPosition (line 37) | public Point getPosition() {
    method getPortal (line 46) | public NetherPortal getPortal() {
    method getInstance (line 50) | @Override

FILE: core/src/main/java/net/minestom/vanilla/system/nether/NetherPortalTeleportEvent.java
  class NetherPortalTeleportEvent (line 15) | public class NetherPortalTeleportEvent implements Event, CancellableEven...
    method NetherPortalTeleportEvent (line 27) | public NetherPortalTeleportEvent(
    method getEntity (line 50) | public @NotNull Entity getEntity() {
    method getPortalBlockPosition (line 57) | public Point getPortalBlockPosition() {
    method getPortal (line 65) | public NetherPortal getPortal() {
    method getTicksSpentInPortal (line 72) | public long getTicksSpentInPortal() {
    method getTargetInstance (line 79) | public Instance getTargetInstance() {
    method setTargetDimension (line 86) | public void setTargetDimension(Instance targetInstance) {
    method getTargetPosition (line 93) | public Point getTargetPosition() {
    method setTargetPosition (line 100) | public void setTargetPosition(Point targetPosition) {
    method getTargetPortal (line 107) | public NetherPortal getTargetPortal() {
    method setTargetPortal (line 114) | public void setTargetPortal(NetherPortal targetPortal) {
    method createsNewPortal (line 121) | public boolean createsNewPortal() {
    method createsNewPortal (line 128) | public void createsNewPortal(boolean createNewPortal) {
    method isCancelled (line 132) | @Override
    method setCancelled (line 137) | @Override

FILE: core/src/main/java/net/minestom/vanilla/system/nether/NetherPortalUpdateEvent.java
  class NetherPortalUpdateEvent (line 15) | public class NetherPortalUpdateEvent implements Event, EntityEvent, Inst...
    method NetherPortalUpdateEvent (line 23) | public NetherPortalUpdateEvent(Entity entity, Point position, NetherPo...
    method getTickSpentInPortal (line 34) | public long getTickSpentInPortal() {
    method getPosition (line 41) | public Point getPosition() {
    method getPortal (line 48) | public NetherPortal getPortal() {
    method getEntity (line 52) | @Override
    method getInstance (line 57) | @Override

FILE: core/src/main/java/net/minestom/vanilla/tag/Tags.java
  type Tags (line 14) | public interface Tags {
    type Items (line 17) | interface Items {
      type Banner (line 24) | interface Banner {
      type Potion (line 39) | interface Potion {
    type Blocks (line 47) | interface Blocks {
      type Campfire (line 48) | interface Campfire {
      type Smelting (line 67) | interface Smelting {

FILE: core/src/main/java/net/minestom/vanilla/utils/DependencySorting.java
  class DependencySorting (line 8) | public class DependencySorting {
    type NamespaceDependent (line 10) | public interface NamespaceDependent<T> {
      method identity (line 11) | T identity();
      method dependencies (line 12) | Set<T> dependencies();
    method sort (line 15) | public static <T, ND extends NamespaceDependent<T>> List<ND> sort(Set<...
    method visit (line 24) | private static <T, ND extends NamespaceDependent<T>> void visit(ND dep...

FILE: core/src/main/java/net/minestom/vanilla/utils/JavaUtils.java
  class JavaUtils (line 6) | public class JavaUtils {
    method randomElement (line 8) | public static <T> T randomElement(RandomGenerator random, Collection<T...

FILE: core/src/main/java/net/minestom/vanilla/utils/MathUtils.java
  class MathUtils (line 9) | public class MathUtils {
    method forEachWithinManhattanDistance (line 10) | public static void forEachWithinManhattanDistance(Point origin, int di...
    method getWithinManhattanDistance (line 37) | public static Set<Point> getWithinManhattanDistance(Point origin, int ...

FILE: core/src/main/java/net/minestom/vanilla/utils/MinestomUtils.java
  class MinestomUtils (line 13) | public class MinestomUtils {
    method initialize (line 19) | public static void initialize() {
    method getEnchantLevel (line 25) | public static int getEnchantLevel(ItemStack itemStack, Enchantment enc...
    method getEnchantKey (line 34) | public static RegistryKey<Enchantment> getEnchantKey(Enchantment encha...

FILE: core/src/main/java/net/minestom/vanilla/utils/ZipUtils.java
  class ZipUtils (line 10) | public class ZipUtils {
    method unzip (line 14) | public static Map<String, byte[]> unzip(InputStream is) throws IOExcep...
    method isDirectory (line 36) | private static boolean isDirectory(ZipEntry entry) {
    method addOnlyEmptyDirectories (line 40) | private static void addOnlyEmptyDirectories(Set<String> dirs, Map<Stri...
    method removeDirectoryMarker (line 67) | private static String removeDirectoryMarker(String path) {
    method replaceIncorrectFileSeparators (line 71) | private static String replaceIncorrectFileSeparators(String path) {

FILE: core/src/test/java/net/minestom/vanilla/files/FileSystemTests.java
  class FileSystemTests (line 9) | public class FileSystemTests {
    method testDynamicWriteRead (line 10) | @Test

FILE: crafting/src/main/java/net/minestom/vanilla/crafting/CraftingFeature.java
  class CraftingFeature (line 19) | public class CraftingFeature {
    method fromRaw (line 31) | public static @NotNull Recipes fromRaw(@NotNull Map<Key, Recipe> recip...
    method filterRecipes (line 59) | @SuppressWarnings("unchecked")
    method buildFromDatapack (line 107) | public static @NotNull Map<Key, Recipe> buildFromDatapack(@NotNull Ser...
    method createEventNode (line 124) | public static @NotNull EventNode<Event> createEventNode(@NotNull Map<K...

FILE: crafting/src/main/java/net/minestom/vanilla/crafting/CraftingRecipes.java
  method init (line 28) | public EventNode<Event> init() {
  method addSquareInputSlots (line 53) | private @NotNull Consumer<InventoryItemChangeEvent> addSquareInputSlots(...
  method addOutputSlot (line 68) | private @NotNull Consumer<InventoryPreClickEvent> addOutputSlot(@NotNull...
  method searchRecipe (line 107) | public @Nullable Recipe.Crafting searchRecipe(int width, int height, @No...
  method tryShapeless (line 139) | public boolean tryShapeless(@NotNull Recipe.Crafting.Shapeless recipe, @...
  method tryShaped (line 185) | public boolean tryShaped(@NotNull Recipe.Crafting.Shaped shaped, int wid...
  method tryShapedInPosition (line 217) | private boolean tryShapedInPosition(@NotNull Recipe.Crafting.Shaped shap...
  method tryTransmute (line 238) | public boolean tryTransmute(@NotNull Recipe.Crafting.Transmute transmute...

FILE: crafting/src/main/java/net/minestom/vanilla/crafting/Recipe.java
  type Recipe (line 21) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 25) | class Holder {
    method createDefaultRegistry (line 31) | static @NotNull DynamicRegistry<StructCodec<? extends Recipe>> createD...
    type Crafting (line 69) | sealed interface Crafting extends Recipe {
      method category (line 74) | @NotNull Category category();
      method result (line 79) | @NotNull ItemStack result();
      method recipeBookCategory (line 81) | @Override
      type Category (line 86) | enum Category {
        method Category (line 93) | Category(RecipeBookCategory category) {
      method codec (line 111) | @Override
      method codec (line 126) | @Override
      method codec (line 142) | @Override
    type Category (line 151) | public enum Category {
    method codec (line 157) | public static @NotNull Codec<Cooking> codec(@Nullable Category default...
    method codec (line 175) | @Override
    method codec (line 187) | @Override
    method codec (line 199) | @Override
    method codec (line 211) | @Override
    method codec (line 234) | @Override
    method codec (line 246) | @Override
    method codec (line 261) | @Override
    method codec (line 273) | @Override
    method codec (line 282) | @Override
    method codec (line 291) | @Override
    method codec (line 300) | @Override
    method codec (line 309) | @Override
    method codec (line 318) | @Override
    method codec (line 327) | @Override
    method codec (line 336) | @Override
    method codec (line 345) | @Override
    method codec (line 354) | @Override
    method codec (line 363) | @Override
    method codec (line 372) | @Override
    method codec (line 381) | @NotNull StructCodec<? extends Recipe> codec();

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/Datapack.java
  type Datapack (line 26) | public interface Datapack {
    method namespacedData (line 28) | Map<String, NamespacedData> namespacedData();
    method loadPrimitiveByteArray (line 30) | static Datapack loadPrimitiveByteArray(FileSystem<byte[]> source) {
    method loadInputStream (line 34) | static Datapack loadInputStream(FileSystem<InputStream> source) {
    method loadByteArray (line 44) | static Datapack loadByteArray(FileSystem<ByteArray> source) {
    method McMeta (line 50) | public McMeta() { // Default
    method cache (line 83) | NamespacedData cache() {
    method fromString (line 105) | public static McFunction fromString(String source) {
    type TagValue (line 123) | public sealed interface TagValue {
      method fromJson (line 125) | static TagValue fromJson(JsonReader reader) throws IOException {
      method fromJson (line 134) | public static ObjectOrTagReference fromJson(JsonReader reader) throw...
    method from (line 168) | public static WorldGen from(FileSystem<ByteArray> worldgen) {
    method cache (line 187) | public WorldGen cache() {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/DatapackLoader.java
  class DatapackLoader (line 50) | public class DatapackLoader {
    method DatapackLoader (line 54) | DatapackLoader() {
    method createMoshiWithAdaptors (line 57) | private static Moshi createMoshiWithAdaptors() {
    method parseJsonFolder (line 141) | static <T> FileSystem<T> parseJsonFolder(FileSystem<ByteArray> source,...
    method adaptor (line 145) | public static <T> Function<String, T> adaptor(Class<T> clazz) {
    method jsonAdaptor (line 155) | public static <T> JsonAdapter<T> jsonAdaptor(Class<T> clazz) {
    method loading (line 161) | public static LoadingContext loading() {
    type LoadingContext (line 169) | public interface LoadingContext {
      method random (line 170) | WorldgenRandom random();
      method whenFinished (line 172) | void whenFinished(Consumer<DatapackFinisher> finishAction);
      method isStatic (line 174) | default boolean isStatic() {
    method random (line 180) | @Override
    method whenFinished (line 185) | @Override
    method isStatic (line 190) | @Override
    type DatapackFinisher (line 196) | public interface DatapackFinisher {
      method datapack (line 197) | Datapack datapack();
    method load (line 200) | public Datapack load(FileSystem<ByteArray> source) {
    method register (line 279) | private static <T> void register(Moshi.Builder builder, Class<T> clazz...
    method register (line 286) | private static <T> void register(Moshi.Builder builder, Class<T> clazz...
    class IoJsonAdaptor (line 290) | private static class IoJsonAdaptor <T> extends JsonAdapter<T> {
      method IoJsonAdaptor (line 293) | public IoJsonAdaptor(IoFunction<JsonReader, T> reader) {
      method fromJson (line 297) | @Override
      method toJson (line 302) | @Override
    type IoFunction (line 307) | public interface IoFunction<T, R> {
      method apply (line 308) | R apply(T t) throws IOException;
    method moshi (line 311) | public static Moshi moshi() {
    method moshi (line 315) | public static <T> JsonUtils.IoFunction<JsonReader, T> moshi(Class<? ex...
    method moshi (line 319) | public static <T> JsonUtils.IoFunction<JsonReader, T> moshi(Type type) {
    method nbtCompoundFromJson (line 325) | private static CompoundBinaryTag nbtCompoundFromJson(JsonReader reader...
    method keyFromJson (line 330) | private static Key keyFromJson(JsonReader reader) throws IOException {
    method uuidFromJson (line 334) | private static UUID uuidFromJson(JsonReader reader) throws IOException {
    method blockFromJson (line 338) | private static Block blockFromJson(JsonReader reader) throws IOExcepti...
    method enchantmentFromJson (line 345) | private static Enchantment enchantmentFromJson(JsonReader reader) thro...
    method entityTypeFromJson (line 349) | private static EntityType entityTypeFromJson(JsonReader reader) throws...
    method materialFromJson (line 353) | private static Material materialFromJson(JsonReader reader) throws IOE...
    method floatRangeFromJson (line 371) | private static Range.Float floatRangeFromJson(JsonReader reader) throw...
    method doubleListFromJson (line 384) | private static DoubleList doubleListFromJson(JsonReader reader) throws...
    method typeDoesntMatch (line 401) | private static boolean typeDoesntMatch(Type type, Class<?> clazz) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/DatapackLoadingFeature.java
  class DatapackLoadingFeature (line 15) | public class DatapackLoadingFeature implements VanillaReimplementation.F...
    method hook (line 19) | @Override
    method current (line 30) | public @NotNull Datapack current() {
    method key (line 35) | @Override
    method dependencies (line 40) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/DatapackUtils.java
  class DatapackUtils (line 17) | public class DatapackUtils {
    method findNoise (line 18) | public static Optional<Noise> findNoise(Datapack datapack, String file) {
    method findDensityFunction (line 22) | public static Optional<DensityFunction> findDensityFunction(Datapack d...
    method findTags (line 27) | public static Set<Key> findTags(Datapack datapack, String tagType, Key...
    method resolveTagItems (line 39) | private static Set<Key> resolveTagItems(Datapack datapack, Datapack.Ta...
    method resolveTagValue (line 47) | private static void resolveTagValue(Datapack datapack, Datapack.Tag.Ta...
    method resolveReferenceTag (line 75) | private static @Nullable Set<Key> resolveReferenceTag(Datapack datapac...
    method findInJsonData (line 96) | private static <T> Optional<T> findInJsonData(String file, Datapack da...

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/advancement/Advancement.java
  type Trigger (line 34) | @SuppressWarnings("unused")
    method from (line 36) | static Trigger<?> from(String trigger) {
    method trigger (line 78) | String trigger();
    method fromJson (line 233) | static Trigger<?> fromJson(JsonReader reader) throws IOException {
  type Conditions (line 239) | public sealed interface Conditions {
    type Count (line 276) | public sealed interface Count {
    type Count (line 362) | public sealed interface Count {
    type Count (line 432) | public interface Count {
    type Count (line 458) | public interface Count {
    type Count (line 479) | public interface Count {
    type Count (line 621) | interface Count {
    type Count (line 718) | public interface Count {
    type Count (line 743) | public interface Count {
    type Property (line 827) | public interface Property {
    type Property (line 968) | public interface Property {
    type Count (line 1095) | public interface Count {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/json/JsonUtils.java
  class JsonUtils (line 20) | public class JsonUtils {
    method jsonReader (line 22) | public static JsonReader jsonReader(String source) {
    type ObjectOrList (line 28) | public interface ObjectOrList<O, E> {
      method isObject (line 30) | boolean isObject();
      method asObject (line 31) | O asObject();
      method isList (line 33) | boolean isList();
      method asList (line 36) | List<E> asList();
    type SingleOrList (line 39) | public interface SingleOrList<T> extends ObjectOrList<T, T>, ListLike<...
      method fromJson (line 40) | static <T> SingleOrList<T> fromJson(Type elementType, JsonReader rea...
      method isObject (line 57) | @Override
      method asObject (line 62) | @Override
      method isList (line 67) | @Override
      method asList (line 72) | @Override
      method list (line 77) | @Override
      method isObject (line 84) | @Override
      method asObject (line 89) | @Override
      method isList (line 94) | @Override
      method asList (line 99) | @Override
      method list (line 104) | @Override
    type IoFunction (line 111) | public interface IoFunction<T, R> {
      method apply (line 112) | R apply(T t) throws IOException;
    method unionStringType (line 115) | public static <T> T unionStringType(JsonReader reader, String key, Fun...
    method unionStringTypeAdapted (line 123) | public static <T> T unionStringTypeAdapted(JsonReader reader, String k...
    method unionStringTypeMap (line 131) | public static <T> T unionStringTypeMap(JsonReader reader, String key, ...
    method unionStringTypeMapAdapted (line 135) | public static <T> T unionStringTypeMapAdapted(JsonReader reader, Strin...
    method unionMapType (line 146) | public static <V, T> T unionMapType(JsonReader reader, String key, IoF...
    method typeMapMapped (line 165) | public static <T> T typeMapMapped(JsonReader reader, Map<JsonReader.To...
    method typeMap (line 169) | public static <T> T typeMap(JsonReader reader, IoFunction<JsonReader.T...
    method findProperty (line 180) | public static <T> @Nullable T findProperty(JsonReader reader, String p...
    method hasProperty (line 192) | public static boolean hasProperty(JsonReader reader, String property) ...
    method readObjectToMap (line 205) | public static <T> Map<String, T> readObjectToMap(JsonReader reader, Io...

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/json/ListLike.java
  type ListLike (line 10) | public interface ListLike<T> extends List<T> {
    method list (line 15) | @NotNull List<T> list();
    method size (line 17) | @Override
    method isEmpty (line 22) | @Override
    method contains (line 27) | @Override
    method iterator (line 32) | @NotNull
    method toArray (line 38) | @NotNull
    method toArray (line 44) | @NotNull
    method add (line 50) | @Override
    method remove (line 55) | @Override
    method containsAll (line 60) | @Override
    method addAll (line 66) | @Override
    method addAll (line 71) | @Override
    method removeAll (line 76) | @Override
    method retainAll (line 81) | @Override
    method clear (line 86) | @Override
    method get (line 91) | @Override
    method set (line 96) | @Override
    method add (line 101) | @Override
    method remove (line 106) | @Override
    method indexOf (line 111) | @Override
    method lastIndexOf (line 116) | @Override
    method listIterator (line 121) | @NotNull
    method listIterator (line 127) | @NotNull
    method subList (line 133) | @NotNull

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/LootTable.java
  type Entry (line 36) | public sealed interface Entry {
    method conditions (line 37) | @Nullable List<Predicate> conditions();
    method type (line 39) | Key type();
    method fromJson (line 41) | static Pool.Entry fromJson(JsonReader reader) throws IOException {
    type ItemGenerator (line 55) | sealed interface ItemGenerator extends Entry {
      method functions (line 56) | @Nullable List<LootFunction> functions();
      method weight (line 57) | @Nullable NumberProvider weight();
      method quality (line 58) | NumberProvider quality();
      method apply (line 63) | List<List<ItemStack>> apply(Datapack datapack, LootContext context);
    method type (line 81) | @Override
    method apply (line 86) | @Override
    method type (line 110) | @Override
    method apply (line 115) | @Override
    method type (line 153) | @Override
    method type (line 173) | @Override
    method apply (line 178) | @Override
    method type (line 198) | @Override
    method apply (line 203) | @Override
    method type (line 217) | @Override
    method type (line 231) | @Override
    method type (line 245) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/NBTPath.java
  type NBTPath (line 12) | public interface NBTPath {
    method fromJson (line 14) | static NBTPath fromJson(JsonReader reader) throws IOException {
    method get (line 24) | @NotNull Map<NBTPath.Single, BinaryTag> get(BinaryTag nbt);
    type Single (line 30) | interface Single extends NBTPath {
      method fromJson (line 32) | static Single fromJson(JsonReader reader) throws IOException {
      method getSingle (line 41) | @Nullable BinaryTag getSingle(BinaryTag nbt);
      method get (line 43) | @Override
      method set (line 56) | @Nullable BinaryTag set(BinaryTag nbt, BinaryTag value);

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/NBTPathImpl.java
  type NBTPathImpl (line 18) | interface NBTPathImpl extends NBTPath {
    method readPath (line 20) | static NBTPathImpl readPath(StringReader reader) throws IOException {
    method readSingle (line 24) | static Single readSingle(StringReader stringReader) throws IOException {
    type NbtPathCollector (line 31) | interface NbtPathCollector<T extends BinaryTag> extends BiConsumer<Sin...
    type Selector (line 37) | interface Selector<T extends BinaryTag> {
      method get (line 45) | void get(@NotNull T source, @NotNull NbtPathCollector<T> selectedEle...
      method fitsGeneric (line 53) | boolean fitsGeneric(@NotNull BinaryTagType<?> type);
    type SingleSelector (line 60) | interface SingleSelector<T extends BinaryTag> extends Selector<T> {
      method get (line 68) | @Nullable BinaryTag get(@NotNull T source);
      method get (line 70) | @Override
  method get (line 80) | public @NotNull Map<Single, BinaryTag> get(@NotNull BinaryTag source) {
  method toString (line 107) | @Override
  method getSingle (line 117) | @Override
  method set (line 130) | @Override
  method retrieveModified (line 142) | private @Nullable BinaryTag retrieveModified(int i, BinaryTag container,...
  method get (line 213) | @Override
  method fitsGeneric (line 219) | @Override
  method toString (line 224) | @Override
  method get (line 237) | @Override
  method fitsGeneric (line 243) | @Override
  method toString (line 248) | @Contract(pure = true)
  method get (line 262) | @Override
  method fitsGeneric (line 267) | @Override
  method toString (line 272) | @Override
  method get (line 290) | @Override
  method fitsGeneric (line 298) | @Override
  method toString (line 303) | @Contract(pure = true)
  method get (line 317) | @Override
  method fitsGeneric (line 329) | @Override
  method toString (line 334) | @Override
  method get (line 349) | @Override
  method fitsGeneric (line 360) | @Override
  method toString (line 365) | @Contract(pure = true)
  type Reader (line 373) | interface Reader {
    method readPath (line 379) | static @NotNull NBTPathImpl readPath(@NotNull StringReader reader) thr...
    method readPathSelector (line 417) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method readInteger (line 457) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method readString (line 476) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method peek (line 523) | @SuppressWarnings("ResultOfMethodCallIgnored")

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/ContextGroups.java
  class ContextGroups (line 13) | public class ContextGroups {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/LootContext.java
  type LootContext (line 13) | public interface LootContext extends Traits {
    type Trait (line 16) | interface Trait<T> {
      method id (line 17) | String id();
      method finder (line 19) | Function<Object, @Nullable T> finder();
      method map (line 21) | default <N> Trait<N> map(Function<T, @Nullable N> mapper) {
      method fromJson (line 25) | static Trait<?> fromJson(JsonReader reader) throws IOException {
    method get (line 32) | <T> @Nullable T get(Trait<T> trait);
    method getOrThrow (line 34) | default <T> T getOrThrow(Trait<T> trait) {
    method get (line 55) | @Override
    method get (line 69) | @Override
    method get (line 83) | @Override
    method get (line 99) | @Override
    method get (line 120) | @Override
    method get (line 133) | @Override
    method get (line 146) | @Override
    method get (line 158) | @Override
    method get (line 171) | @Override
    method get (line 185) | @Override
    method get (line 211) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/MappedTraitImpl.java
  method id (line 8) | @Override
  method finder (line 13) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/TraitImpl.java
  method finder (line 8) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/Traits.java
  type Traits (line 10) | interface Traits {
    method fromId (line 28) | static LootContext.Trait<?> fromId(String id) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/Util.java
  class Util (line 9) | class Util {
    type EmptyLootContext (line 11) | public interface EmptyLootContext extends LootContext {
      method get (line 12) | @Override
    type LootContextTraitMap (line 18) | public interface LootContextTraitMap<C extends LootContext> {
      method obtain (line 19) | <T> T obtain(C context, LootContext.Trait<T> trait);
      method builder (line 21) | static <C extends LootContext> Builder<C> builder() {
      type Builder (line 25) | interface Builder<C extends LootContext> {
        method put (line 26) | <T> Builder<C> put(LootContext.Trait<T> trait, Function<C, T> value);
        method build (line 28) | LootContextTraitMap<C> build();
    class BuilderImpl (line 32) | static class BuilderImpl<C extends LootContext> implements LootContext...
      method put (line 35) | @Override
      method build (line 41) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/InBuiltLootFunctions.java
  type InBuiltLootFunctions (line 39) | @SuppressWarnings("unused")
    type ApplyBonus (line 43) | interface ApplyBonus extends LootFunction {
      method function (line 45) | @Override
      method enchantment (line 50) | Key enchantment();
      method formula (line 52) | Key formula();
      method fromJson (line 54) | static ApplyBonus fromJson(JsonReader reader) throws IOException {
      method formula (line 63) | @Override
      method apply (line 71) | @Override
      method formula (line 89) | @Override
      method apply (line 97) | @Override
      method formula (line 108) | @Override
      method apply (line 113) | @Override
    method function (line 125) | @Override
    method apply (line 130) | @Override
    method function (line 151) | @Override
    method apply (line 156) | @Override
    type Source (line 166) | public sealed interface Source {
      method type (line 168) | String type();
      method nbt (line 170) | BinaryTag nbt(LootFunction.Context context);
      method fromJson (line 172) | static Source fromJson(JsonReader reader) throws IOException {
      method type (line 187) | @Override
      method nbt (line 192) | @Override
      method type (line 200) | @Override
      method nbt (line 205) | @Override
    type Operation (line 213) | public sealed interface Operation {
      method source (line 215) | NBTPath.Single source();
      method target (line 217) | NBTPath.Single target();
      method op (line 219) | String op();
      method apply (line 221) | BinaryTag apply(BinaryTag source, BinaryTag target);
      method applyOperation (line 223) | default BinaryTag applyOperation(BinaryTag source, BinaryTag itemSta...
      method fromJson (line 230) | static Operation fromJson(JsonReader reader) throws IOException {
      method op (line 240) | @Override
      method apply (line 245) | @Override
      method op (line 252) | @Override
      method apply (line 257) | @Override
      method op (line 274) | @Override
      method apply (line 279) | @Override
      method Operation (line 597) | Operation(String id) {
      method getId (line 601) | public String getId() {
      method toMinestom (line 605) | public AttributeOperation toMinestom() {
    method function (line 305) | @Override
    method apply (line 310) | @Override
    method function (line 332) | @Override
    method apply (line 337) | @Override
    method function (line 365) | @Override
    method apply (line 370) | @Override
    method function (line 394) | @Override
    method apply (line 399) | @Override
    method function (line 425) | @Override
    method apply (line 430) | @Override
    method function (line 455) | @Override
    method apply (line 460) | @Override
    method function (line 482) | @Override
    method apply (line 487) | @Override
    method function (line 497) | @Override
    method apply (line 502) | @Override
    type Limit (line 507) | public interface Limit {
      method limit (line 508) | ItemStack limit(LootFunction.Context context);
      method fromJson (line 510) | static Limit fromJson(JsonReader reader) throws IOException {
      method limit (line 518) | @Override
      method limit (line 525) | @Override
    method function (line 540) | @Override
    method apply (line 545) | @Override
    method function (line 574) | @Override
    method apply (line 579) | @Override
    type Operation (line 590) | public enum Operation {
      method source (line 215) | NBTPath.Single source();
      method target (line 217) | NBTPath.Single target();
      method op (line 219) | String op();
      method apply (line 221) | BinaryTag apply(BinaryTag source, BinaryTag target);
      method applyOperation (line 223) | default BinaryTag applyOperation(BinaryTag source, BinaryTag itemSta...
      method fromJson (line 230) | static Operation fromJson(JsonReader reader) throws IOException {
      method op (line 240) | @Override
      method apply (line 245) | @Override
      method op (line 252) | @Override
      method apply (line 257) | @Override
      method op (line 274) | @Override
      method apply (line 279) | @Override
      method Operation (line 597) | Operation(String id) {
      method getId (line 601) | public String getId() {
      method toMinestom (line 605) | public AttributeOperation toMinestom() {
    type Slot (line 614) | public enum Slot {
      method Slot (line 624) | Slot(String id) {
      method getId (line 628) | public String getId() {
      method toMinestom (line 632) | public EquipmentSlotGroup toMinestom() {
    method AttributeModifier (line 647) | public AttributeModifier(String name, Key attribute, Operation operati...
    method apply (line 652) | public AttributeList.Modifier apply(Context context) {
    method function (line 672) | @Override
    method toPattern (line 678) | public Tags.Items.Banner.Pattern toPattern() {
    method apply (line 684) | @Override
    method function (line 709) | @Override
    method apply (line 714) | @Override
    method function (line 724) | @Override
    method apply (line 729) | @Override
    method function (line 751) | @Override
    method apply (line 756) | @Override
    method function (line 779) | @Override
    method apply (line 784) | @Override
    method function (line 814) | @Override
    method apply (line 819) | @Override
    method function (line 829) | @Override
    method apply (line 834) | @Override
    method function (line 844) | @Override
    method apply (line 849) | @Override
    method function (line 873) | @Override
    method apply (line 878) | @Override
    method function (line 887) | @Override
    method apply (line 892) | @Override
    method function (line 906) | @Override
    method apply (line 911) | @Override
    method function (line 920) | @Override
    method apply (line 928) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/InBuiltPredicates.java
  type InBuiltPredicates (line 27) | interface InBuiltPredicates {
    method condition (line 35) | @Override
    method test (line 40) | @Override
    method condition (line 62) | @Override
    method test (line 67) | @Override
    type Property (line 87) | public interface Property {
      method test (line 88) | boolean test(Block block, String value);
      method fromJson (line 90) | static Property fromJson(JsonReader reader) throws IOException {
      method test (line 98) | @Override
      method test (line 106) | @Override
    method condition (line 121) | @Override
    method test (line 126) | @Override
    method condition (line 140) | @Override
    method test (line 145) | @Override
    method condition (line 163) | @Override
    method test (line 168) | @Override
    type Score (line 174) | public sealed interface Score {
      method test (line 175) | boolean test();
      method fromJson (line 177) | static Score fromJson(JsonReader reader) throws IOException {
      method test (line 185) | @Override
      method test (line 192) | @Override
    method condition (line 205) | @Override
    method test (line 210) | @Override
    method condition (line 220) | @Override
    method test (line 225) | @Override
    method condition (line 241) | @Override
    method test (line 246) | @Override
    method condition (line 259) | @Override
    method test (line 264) | @Override
    method condition (line 276) | @Override
    method test (line 281) | @Override
    method condition (line 293) | @Override
    method test (line 298) | @Override
    method condition (line 321) | @Override
    method test (line 326) | @Override
    method condition (line 337) | @Override
    method test (line 342) | @Override
    method condition (line 356) | @Override
    method test (line 361) | @Override
    method condition (line 382) | @Override
    method test (line 387) | @Override
    type Value (line 393) | public sealed interface Value {
      method fromJson (line 395) | static Value fromJson(JsonReader reader) throws IOException {
    method condition (line 420) | @Override
    method test (line 425) | @Override
    type Range (line 431) | public sealed interface Range {
      method fromJson (line 432) | static Range fromJson(JsonReader reader) throws IOException {
    method condition (line 453) | @Override
    method test (line 458) | @Override
    method condition (line 470) | @Override
    method test (line 475) | @Override
    method condition (line 486) | @Override
    method test (line 491) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/LootFunction.java
  type LootFunction (line 15) | public interface LootFunction extends InBuiltLootFunctions {
    method function (line 20) | Key function();
    method apply (line 28) | ItemStack apply(Context context);
    method fromJson (line 30) | static LootFunction fromJson(JsonReader reader) throws IOException {
    type Context (line 63) | interface Context extends LootContext {
      method random (line 69) | RandomGenerator random();
      method itemStack (line 76) | ItemStack itemStack();

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/Predicate.java
  type Predicate (line 9) | public interface Predicate extends InBuiltPredicates {
    method condition (line 11) | String condition();
    method test (line 13) | boolean test(LootContext context);
    method fromJson (line 15) | static Predicate fromJson(JsonReader reader) throws IOException {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/nbt/NBTUtils.java
  class NBTUtils (line 16) | public class NBTUtils {
    method compareNBT (line 29) | public static boolean compareNBT(@Nullable BinaryTag guarantee, @Nulla...
    method readCompoundSNBT (line 80) | public static @Nullable CompoundBinaryTag readCompoundSNBT(@NotNull St...

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/number/DoubleNumberProviders.java
  type DoubleNumberProviders (line 5) | interface DoubleNumberProviders {
    method apply (line 8) | @Override
    method apply (line 15) | @Override
    method apply (line 24) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/number/IntNumberProviders.java
  type IntNumberProviders (line 5) | interface IntNumberProviders {
    method apply (line 8) | @Override
    method apply (line 15) | @Override
    method apply (line 24) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/number/NumberProvider.java
  type NumberProvider (line 10) | public interface NumberProvider {
    method asInt (line 12) | Int asInt();
    method asDouble (line 14) | Double asDouble();
    type Context (line 16) | interface Context {
      method random (line 18) | RandomGenerator random();
    type Int (line 21) | interface Int extends NumberProvider, IntNumberProviders {
      method apply (line 23) | int apply(Context context);
      method asDouble (line 25) | default Double asDouble() {
      method asInt (line 29) | default Int asInt() {
      method fromJson (line 33) | static NumberProvider.Int fromJson(JsonReader reader) throws IOExcep...
      method constant (line 44) | static NumberProvider.Int constant(int value) {
      method uniform (line 48) | static NumberProvider.Int uniform(NumberProvider.Int min, NumberProv...
      method binomial (line 52) | static NumberProvider.Int binomial(NumberProvider.Int n, NumberProvi...
    type Double (line 57) | interface Double extends NumberProvider, DoubleNumberProviders {
      method apply (line 59) | double apply(Context context);
      method asInt (line 61) | default Int asInt() {
      method asDouble (line 65) | default Double asDouble() {
      method fromJson (line 69) | static NumberProvider.Double fromJson(JsonReader reader) throws IOEx...
      method constant (line 80) | static NumberProvider.Double constant(double value) {
      method uniform (line 84) | static NumberProvider.Double uniform(NumberProvider.Double min, Numb...
      method binomial (line 88) | static NumberProvider.Double binomial(NumberProvider.Int n, NumberPr...

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/recipe/Recipe.java
  type Recipe (line 18) | public interface Recipe {
    method type (line 20) | @NotNull Key type();
    method group (line 22) | @Nullable String group();
    method fromJson (line 24) | static Recipe fromJson(JsonReader reader) throws IOException {
    type CookingRecipe (line 54) | interface CookingRecipe extends Recipe {
      method ingredient (line 55) | @NotNull List<Ingredient> ingredient();
      method result (line 56) | @NotNull SingleResult result();
      method experience (line 57) | double experience();
      method cookingTime (line 58) | @Optional Integer cookingTime();
    type Ingredient (line 61) | interface Ingredient {
      method fromJson (line 63) | static Ingredient fromJson(JsonReader reader) throws IOException {
      type Single (line 83) | interface Single extends Ingredient {
        method fromJson (line 84) | static Single fromJson(JsonReader reader) throws IOException {
    method type (line 115) | @Override
    method type (line 123) | @Override
    method type (line 130) | @Override
    method type (line 137) | @Override
    method type (line 145) | @Override
    type Special (line 151) | sealed interface Special extends Recipe {
      method type (line 154) | @Override
      method type (line 161) | @Override
      method type (line 168) | @Override
      method type (line 175) | @Override
      method type (line 182) | @Override
      method type (line 189) | @Override
      method type (line 196) | @Override
      method type (line 203) | @Override
      method type (line 210) | @Override
      method type (line 217) | @Override
      method type (line 224) | @Override
      method type (line 231) | @Override
    method type (line 240) | @Override
    method type (line 248) | @Override
    method type (line 256) | @Override
    method type (line 263) | @Override
    type Smithing (line 269) | interface Smithing extends Recipe {
      method template (line 271) | Ingredient.Single template();
      method base (line 272) | Ingredient.Single base();
      method addition (line 273) | Ingredient.Single addition();
      method type (line 274) | default @NotNull Key type() {
    method type (line 281) | @Override
    method type (line 289) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/tags/ConditionsFor.java
  class ConditionsFor (line 3) | public class ConditionsFor {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/tags/Tag.java
  method Tag (line 7) | public Tag(String string) {
  method asString (line 11) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/Biome.java
  type TemperatureModifier (line 47) | public enum TemperatureModifier {
  type Sound (line 55) | public interface Sound {
    method type (line 56) | Key type();
    method fromJson (line 65) | static Sound fromJson(JsonReader reader) throws IOException {
    method type (line 81) | @Override
    method type (line 91) | @Override
  type Options (line 124) | public interface Options {
    method type (line 130) | Key type();
    method fromJson (line 139) | static Options fromJson(JsonReader reader) throws IOException {
    method type (line 158) | @Override
    method type (line 168) | @Override
    method type (line 178) | @Override
    method type (line 196) | @Override
    method type (line 206) | @Override
    method type (line 216) | @Override
    method type (line 226) | @Override
    method type (line 236) | @Override
    type PositionSource (line 244) | interface PositionSource {
      method type (line 245) | Key type();
      method fromJson (line 254) | static PositionSource fromJson(JsonReader reader) throws IOException {
      method type (line 266) | @Override
      method type (line 276) | @Override
    method type (line 288) | @Override
  type CarversList (line 324) | public interface CarversList {
    method carvers (line 327) | List<Carver> carvers();
    method fromJson (line 329) | static CarversList fromJson(JsonReader reader) throws IOException {
    type Single (line 343) | interface Single extends CarversList {
      method carver (line 344) | Carver carver();
      method carvers (line 346) | default List<Carver> carvers() {
      method fromJson (line 350) | static Single fromJson(JsonReader reader) throws IOException {
      class Reference (line 358) | final class Reference implements Single {
        method Reference (line 362) | public Reference(Key id) {
        method carver (line 382) | @Override
        method id (line 393) | public Key id() {
        method equals (line 397) | @Override
        method hashCode (line 405) | @Override
        method toString (line 410) | @Override
    method carvers (line 422) | @Override
  type MobCategory (line 439) | public enum MobCategory {
  type GrassColorModifier (line 461) | public enum GrassColorModifier {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/BlockState.java
  method toMinestom (line 12) | public Block toMinestom() {
  method fromJson (line 17) | public static BlockState fromJson(JsonReader reader) throws IOException {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/Carver.java
  method fromJson (line 18) | public static Carver fromJson(JsonReader reader) throws IOException {
  type BaseConfig (line 47) | public interface BaseConfig {
    method probability (line 50) | float probability();
    method y (line 53) | HeightProvider y();
    method lava_level (line 56) | HeightProvider lava_level();
    method replaceable (line 59) | JsonUtils.SingleOrList<Block> replaceable();
    method debug_settings (line 68) | @Optional

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/DensityFunction.java
  type DensityFunction (line 10) | public interface DensityFunction extends DensityFunctions, NumberFunctio...
    method compute (line 11) | double compute(Context context);
    method minValue (line 13) | default double minValue() {
    method maxValue (line 17) | double maxValue();
    method fromJson (line 19) | static DensityFunction fromJson(JsonReader reader) throws IOException {
    method context (line 67) | static DensityFunction.Context context(double x, double y, double z) {
    type Context (line 75) | interface Context {
      method x (line 76) | double x();
      method blockX (line 78) | default int blockX() {
      method y (line 82) | double y();
      method blockY (line 84) | default int blockY() {
      method z (line 88) | double z();
      method blockZ (line 90) | default int blockZ() {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/DensityFunctions.java
  type DensityFunctions (line 20) | interface DensityFunctions {
    class ContextImpl (line 22) | class ContextImpl implements DensityFunction.Context {
      method x (line 27) | @Override
      method y (line 32) | @Override
      method z (line 37) | @Override
    method compute (line 46) | @Override
    method maxValue (line 51) | @Override
    method minValue (line 56) | @Override
    method compute (line 65) | @Override
    method maxValue (line 70) | @Override
    method minValue (line 75) | @Override
    method compute (line 83) | @Override
    method maxValue (line 88) | @Override
    method minValue (line 93) | @Override
    class OldBlendedNoise (line 99) | class OldBlendedNoise implements DensityFunction {
      method OldBlendedNoise (line 103) | private OldBlendedNoise(Params params) {
      method fromJson (line 110) | public static OldBlendedNoise fromJson(JsonReader reader) throws IOE...
      method compute (line 115) | @Override
      method maxValue (line 120) | @Override
      method minValue (line 125) | @Override
    type Wrapped (line 131) | interface Wrapped extends DensityFunction {
      method wrapped (line 132) | DensityFunction wrapped();
      method minValue (line 134) | @Override
      method maxValue (line 139) | @Override
    class FlatCache (line 145) | class FlatCache implements Wrapped {
      method FlatCache (line 153) | public FlatCache(DensityFunction argument) {
      method compute (line 157) | public double compute(Context context) {
      method wrapped (line 168) | @Override
    class Interpolated (line 174) | class Interpolated implements Wrapped {
      method Interpolated (line 180) | public Interpolated(DensityFunction argument) {
      method wrapped (line 184) | @Override
      method cache (line 189) | private DoubleStorage cache() {
      method compute (line 196) | @Override
      method computeCorner (line 220) | private double computeCorner(int x, int y, int z) {
      method argument (line 224) | public DensityFunction argument() {
    class Cache2D (line 229) | class Cache2D implements Wrapped {
      method Cache2D (line 237) | public Cache2D(DensityFunction argument) {
      method cache (line 241) | private DoubleStorage cache() {
      method compute (line 248) | public double compute(Context context) {
      method wrapped (line 255) | @Override
    class CacheOnce (line 261) | class CacheOnce implements Wrapped {
      method CacheOnce (line 268) | public CacheOnce(DensityFunction argument) {
      method compute (line 272) | public double compute(Context context) {
      method wrapped (line 284) | @Override
    method compute (line 293) | public double compute(Context context) {
    method compute (line 301) | @Override
    method maxValue (line 306) | @Override
    method minValue (line 311) | @Override
    class EndIslands (line 317) | class EndIslands implements DensityFunction {
      method EndIslands (line 320) | public EndIslands() {
      method EndIslands (line 324) | public EndIslands(long seed) {
      method calculateHeightScale (line 330) | private double calculateHeightScale(int x, int z) {
      method compute (line 354) | @Override
      method minValue (line 359) | @Override
      method maxValue (line 364) | @Override
    type RarityValueMapper (line 372) | public enum RarityValueMapper {
      method RarityValueMapper (line 379) | RarityValueMapper(Double2DoubleFunction mapper, double maxValue) {
      method mapper (line 384) | public Double2DoubleFunction mapper() {
      method maxValue (line 388) | public double maxValue() {
    method compute (line 393) | @Override
    method minValue (line 399) | @Override
    method maxValue (line 404) | @Override
    method rarityValueMapper1 (line 409) | private static double rarityValueMapper1(double value) {
    method rarityValueMapper2 (line 421) | private static double rarityValueMapper2(double value) {
    method compute (line 440) | @Override
    method minValue (line 445) | public double minValue() {
    method maxValue (line 449) | public double maxValue() {
    method compute (line 455) | public double compute(Context context) {
    method maxValue (line 463) | @Override
    method minValue (line 468) | @Override
    method compute (line 477) | public double compute(Context context) {
    method minValue (line 483) | public double minValue() {
    method maxValue (line 487) | public double maxValue() {
    method compute (line 494) | public double compute(Context context) {
    method minValue (line 500) | @Override
    method maxValue (line 505) | @Override
    method compute (line 513) | public double compute(Context context) {
    method minValue (line 519) | @Override
    method maxValue (line 524) | @Override
    method compute (line 532) | @Override
    method maxValue (line 540) | @Override
    method minValue (line 545) | @Override
    method compute (line 552) | @Override
    method minValue (line 558) | public double minValue() {
    method maxValue (line 562) | public double maxValue() {
    method compute (line 569) | public double compute(Context context) {
    method minValue (line 574) | public double minValue() {
    method maxValue (line 578) | public double maxValue() {
    method compute (line 585) | public double compute(Context context) {
    method minValue (line 590) | public double minValue() {
    method maxValue (line 598) | public double maxValue() {
    method compute (line 605) | public double compute(Context context) {
    method minValue (line 610) | public double minValue() {
    method maxValue (line 614) | public double maxValue() {
    method compute (line 621) | public double compute(Context context) {
    method minValue (line 626) | public double minValue() {
    method maxValue (line 630) | public double maxValue() {
    method compute (line 637) | public double compute(Context context) {
    method minValue (line 642) | public double minValue() {
    method maxValue (line 646) | public double maxValue() {
    method compute (line 653) | public double compute(Context context) {
    method minValue (line 658) | public double minValue() {
    method maxValue (line 662) | public double maxValue() {
    method compute (line 669) | public double compute(Context context) {
    method minValue (line 675) | public double minValue() {
    method maxValue (line 679) | public double maxValue() {
    method compute (line 685) | @Override
    method minValue (line 690) | @Override
    method maxValue (line 695) | @Override
    method compute (line 702) | @Override
    method minValue (line 707) | @Override
    method maxValue (line 712) | @Override
    method compute (line 719) | @Override
    method minValue (line 724) | @Override
    method maxValue (line 729) | @Override
    method compute (line 736) | @Override
    method minValue (line 741) | @Override
    method maxValue (line 746) | @Override
    method compute (line 753) | public double compute(Context context) {
    method minValue (line 757) | public double minValue() {
    method maxValue (line 761) | public double maxValue() {
    method compute (line 768) | public double compute(Context context) {
    method minValue (line 772) | public double minValue() {
    method maxValue (line 776) | public double maxValue() {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/FloatProvider.java
  type FloatProvider (line 9) | public interface FloatProvider {
    method type (line 10) | Key type();
    method fromJson (line 12) | static FloatProvider fromJson(JsonReader reader) throws IOException {
    method type (line 28) | @Override
    method type (line 41) | @Override
    method type (line 56) | @Override
    method type (line 68) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/HeightProvider.java
  type HeightProvider (line 11) | public sealed interface HeightProvider {
    method type (line 13) | Key type();
    method fromJson (line 15) | static HeightProvider fromJson(JsonReader reader) throws IOException {
    method type (line 35) | @Override
    method type (line 44) | @Override
    method type (line 54) | @Override
    method type (line 64) | @Override
    method type (line 74) | @Override
    method type (line 82) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/LazyLoadedDensityFunction.java
  class LazyLoadedDensityFunction (line 7) | class LazyLoadedDensityFunction implements DensityFunction {
    method LazyLoadedDensityFunction (line 11) | public LazyLoadedDensityFunction(String id, DatapackLoader.LoadingCont...
    method densityFunction (line 16) | private DensityFunction densityFunction() {
    method compute (line 23) | @Override
    method maxValue (line 28) | @Override
    method minValue (line 33) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/NoiseSettings.java
  method cellHeight (line 33) | public static int cellHeight(NoiseSettings settings) {
  method cellWidth (line 36) | public static int cellWidth(NoiseSettings settings) {
  method cellCountY (line 39) | public static double cellCountY(NoiseSettings settings) {
  method minCellY (line 42) | public static double minCellY(NoiseSettings settings) {
  type SlideSettings (line 61) | interface SlideSettings {
    method target (line 62) | double target();
    method size (line 64) | double size();
    method offset (line 66) | double offset();
    method fromJson (line 68) | static SlideSettings fromJson(Object obj) {
    method apply (line 94) | static double apply(SlideSettings slide, double density, double y) {
  method instantiate (line 140) | public static NormalNoise instantiate(WorldgenRandom.Positional random, ...
  type SurfaceRule (line 161) | public interface SurfaceRule {
    method type (line 162) | Key type();
    method apply (line 164) | Pos2Block apply(Context context);
    type Context (line 166) | interface Context extends VerticalAnchor.Context {
      method biome (line 167) | Key biome();
      method minY (line 169) | int minY();
      method maxY (line 170) | int maxY();
      method blockX (line 172) | int blockX();
      method blockY (line 173) | int blockY();
      method blockZ (line 174) | int blockZ();
      method random (line 176) | WorldgenRandom random(String string);
      method stoneDepthAbove (line 179) | int stoneDepthAbove();
      method surfaceDepth (line 180) | int surfaceDepth();
      method waterHeight (line 181) | int waterHeight();
      method minSurfaceLevel (line 182) | int minSurfaceLevel();
      method stoneDepthBelow (line 183) | int stoneDepthBelow();
      method surfaceSecondary (line 184) | double surfaceSecondary();
    type Pos2Block (line 187) | interface Pos2Block {
      method apply (line 188) | @Nullable Block apply(int x, int y, int z);
    method fromJson (line 191) | static SurfaceRule fromJson(JsonReader reader) throws IOException {
    method type (line 202) | @Override
    method apply (line 207) | @Override
    method type (line 215) | @Override
    method apply (line 220) | @Override
    method type (line 227) | @Override
    method apply (line 232) | @Override
    method type (line 248) | @Override
    method apply (line 253) | @Override
    type SurfaceRuleCondition (line 302) | interface SurfaceRuleCondition {
      method type (line 303) | Key type();
      method test (line 305) | boolean test(SurfaceRule.Context context);
      method fromJson (line 307) | static SurfaceRuleCondition fromJson(JsonReader reader) throws IOExc...
      method type (line 325) | @Override
      method test (line 330) | @Override
      method type (line 337) | @Override
      method test (line 342) | @Override
      method type (line 350) | @Override
      method test (line 355) | @Override
      method type (line 372) | @Override
      method test (line 377) | @Override
      method type (line 385) | @Override
      method test (line 390) | @Override
      method type (line 401) | @Override
      method test (line 406) | @Override
      method type (line 414) | @Override
      method test (line 419) | @Override
      method type (line 427) | @Override
      method test (line 432) | @Override
      method type (line 439) | @Override
      method test (line 444) | @Override
      method type (line 452) | @Override
      method test (line 457) | @Override
      method type (line 464) | @Override
      method test (line 469) | @Override
      type SurfaceType (line 480) | enum SurfaceType {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/Structure.java
  method fromInput (line 55) | public static Structure fromInput(ByteArray content) {
  method parsePoint (line 84) | private static Point parsePoint(ListBinaryTag nbtSize) {
  method parseDoublePoint (line 88) | private static Point parseDoublePoint(ListBinaryTag nbtSize) {
  method parseBlockState (line 92) | private static BlockState parseBlockState(CompoundBinaryTag block) {
  method parsePalette (line 103) | private static Set<BlockState> parsePalette(ListBinaryTag nbtPalette) {
  method parsePalettes (line 110) | private static Set<Set<BlockState>> parsePalettes(ListBinaryTag nbtPalet...
  method parseBlocks (line 120) | private static List<Block> parseBlocks(ListBinaryTag nbtBlocks) {
  method parseEntities (line 131) | private static List<Entity> parseEntities(ListBinaryTag nbtEntities) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/VerticalAnchor.java
  type VerticalAnchor (line 7) | sealed public interface VerticalAnchor {
    type Context (line 10) | interface Context {
      method minY (line 11) | int minY();
      method maxY (line 12) | int maxY();
    method apply (line 15) | int apply(Context context);
    method fromJson (line 17) | static VerticalAnchor fromJson(JsonReader reader) throws IOException {
    method apply (line 34) | @Override
    method apply (line 41) | @Override
    method apply (line 48) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/WorldgenContext.java
  type WorldgenContext (line 5) | public interface WorldgenContext {
    method create (line 7) | static WorldgenContext create(DimensionType dimension) {
    method minY (line 11) | default int minY() {
    method maxY (line 14) | default int maxY() {
    method dimension (line 18) | DimensionType dimension();

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/WorldgenRegistries.java
  class WorldgenRegistries (line 6) | public class WorldgenRegistries {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/biome/BiomeSource.java
  type BiomeSource (line 8) | public interface BiomeSource extends BiomeSources {
    method getBiome (line 13) | Key getBiome(int x, int y, int z, Climate.Sampler climateSampler);
    method checkerBoard (line 29) | static BiomeSource checkerBoard(int shift, Key... biomes) {
    method fixed (line 33) | static BiomeSource fixed(Key biome) {
    method multiNoise (line 37) | static BiomeSource multiNoise(Climate.Parameters<Key> parameters) {
    method theEnd (line 41) | static BiomeSource theEnd() {
    method fromJson (line 45) | static BiomeSource fromJson(Object obj) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/biome/BiomeSources.java
  type BiomeSources (line 16) | interface BiomeSources {
    method CheckerboardBiomeSource (line 20) | public CheckerboardBiomeSource(int shift, Key[] biomes) {
    method getBiome (line 30) | @Override
    method fromJson (line 36) | public static CheckerboardBiomeSource fromJson(Object obj) {
    method getBiome (line 52) | @Override
    method fromJson (line 57) | public static FixedBiomeSource fromJson(Object obj) {
    method getBiome (line 66) | @Override
    method fromJson (line 72) | public static MultiNoiseBiomeSource fromJson(Object obj) {
    method getBiome (line 99) | @Override
    method fromJson (line 126) | public static TheEndBiomeSource fromJson(Object obj) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/biome/Climate.java
  class Climate (line 15) | public class Climate {
    method target (line 21) | public static TargetPoint target(double temperature, double humidity, ...
    method parameters (line 28) | public static ParamPoint parameters(double temperature, double humidit...
    method param (line 38) | public static Param param(double min, double max) {
    method param (line 42) | public static Param param(double value) {
    method param (line 46) | public static Param param(Param value) {
    method param (line 50) | public static Param param(Object value) {
    method distance (line 74) | public double distance(Param param) {
    method union (line 89) | public Param union(Param param) {
    method fromJson (line 101) | public static Param fromJson(Object obj) {
    method fittness (line 132) | public double fittness(ParamPoint point) {
    method space (line 157) | public Param[] space() {
    method fromJson (line 173) | public static ParamPoint fromJson(Object obj) {
    method offset (line 209) | public double offset() {
    method toArray (line 216) | public double[] toArray() {
    class Parameters (line 233) | public static class Parameters<T> {
      method Parameters (line 236) | public Parameters(Map<ParamPoint, Supplier<T>> things) {
      method find (line 240) | public T find(TargetPoint target) {
    method fromRouter (line 266) | public static Sampler fromRouter(NoiseSettings.NoiseRouter router) {
    method sample (line 270) | public TargetPoint sample(int x, int y, int z) {
    type DistanceMetric (line 277) | interface DistanceMetric<T> {
      method distance (line 278) | double distance(RNode<T> node, double[] values);
    class RTree (line 283) | public static class RTree<T> {
      method RTree (line 298) | public RTree(Map<ParamPoint, Supplier<T>> points) {
      method build (line 350) | private static <T> RNode<T> build(List<RNode<T>> nodes) {
      method sort (line 402) | private static <N extends RNode<?>> List<N> sort(List<N> nodes, int ...
      method bucketize (line 432) | private static <T> List<RSubTree<T>> bucketize(List<RNode<T>> nodes) {
      method area (line 457) | private static double area(Collection<Param> params) {
      method search (line 471) | public T search(TargetPoint target, DistanceMetric<T> distance) {
    class RNode (line 491) | static abstract class RNode<T> {
      method RNode (line 494) | public RNode(Param[] space) {
      method search (line 498) | public abstract RLeaf<T> search(double[] values, DistanceMetric<T> d...
      method distance (line 500) | public double distance(double[] values) {
      method space (line 508) | public List<Param> space() {
    class RSubTree (line 541) | static class RSubTree<T> extends RNode<T> {
      method RSubTree (line 544) | public RSubTree(List<RNode<T>> children) {
      method buildSpace (line 549) | private static <T> Param[] buildSpace(List<RNode<T>> nodes) {
      method search (line 562) | @Override
    class RLeaf (line 589) | static class RLeaf<T> extends RNode<T> {
      method RLeaf (line 592) | public RLeaf(ParamPoint point, Supplier<T> thing) {
      method search (line 597) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/math/CubicSpline.java
  type CubicSpline (line 15) | public interface CubicSpline extends NumberFunction<DensityFunction.Cont...
    method fromJson (line 17) | static CubicSpline fromJson(JsonReader reader) throws IOException {
    method min (line 26) | double min();
    method max (line 28) | double max();
    method min (line 30) | @Override
    method max (line 35) | @Override
    method compute (line 40) | @Override
    method compute (line 54) | @Override
    method minMax (line 89) | private CachedMinMax minMax() {
    method min (line 157) | @Override
    method max (line 162) | @Override
    method linearExtend (line 170) | private static double linearExtend(double location, Point point, doubl...

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/math/NumberFunction.java
  type NumberFunction (line 3) | public interface NumberFunction<C> {
    method compute (line 4) | double compute(C c);

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/math/SplineInterpolator.java
  class SplineInterpolator (line 8) | public class SplineInterpolator {
    method SplineInterpolator (line 14) | private SplineInterpolator(DoubleList x, DoubleList y, double[] m) {
    method createMonotoneCubicSpline (line 34) | public static SplineInterpolator createMonotoneCubicSpline(DoubleList ...
    method interpolate (line 86) | public double interpolate(double x) {
    method toString (line 117) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/BlendedNoise.java
  class BlendedNoise (line 7) | public class BlendedNoise implements Noise {
    method BlendedNoise (line 20) | public BlendedNoise(WorldgenRandom random, double xzScale, double ySca...
    method sample (line 32) | @Override
    method minValue (line 80) | @Override
    method maxValue (line 85) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/ImprovedNoise.java
  class ImprovedNoise (line 6) | public class ImprovedNoise implements Noise {
    method ImprovedNoise (line 13) | public ImprovedNoise(WorldgenRandom random) {
    method sample (line 30) | public double sample(double x, double y, double z) {
    method minValue (line 34) | @Override
    method maxValue (line 39) | @Override
    method sample (line 44) | public double sample(double x, double y, double z, double yScale, doub...
    method sampleAndLerp (line 64) | private double sampleAndLerp(int a, int b, int c, double d, double e, ...
    method gradDot (line 90) | public static double gradDot(int a, double b, double c, double d) {
    method P (line 95) | private int P(int i) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/LazyLoadedNoise.java
  class LazyLoadedNoise (line 8) | class LazyLoadedNoise implements Noise {
    method LazyLoadedNoise (line 11) | public LazyLoadedNoise(String id, DatapackLoader.LoadingContext contex...
    method noise (line 15) | private @NotNull Noise noise() {
    method sample (line 22) | @Override
    method minValue (line 27) | @Override
    method maxValue (line 32) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/Noise.java
  type Noise (line 9) | public interface Noise {
    method sample (line 12) | double sample(double x, double y, double z);
    method minValue (line 14) | double minValue();
    method maxValue (line 15) | double maxValue();
    method fromJson (line 17) | static Noise fromJson(JsonReader reader) throws IOException {
  method sample (line 39) | @Override
  method minValue (line 44) | @Override
  method maxValue (line 49) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/NormalNoise.java
  class NormalNoise (line 6) | public class NormalNoise implements Noise {
    method NormalNoise (line 18) | public NormalNoise(WorldgenRandom random, Config config) {
    method sample (line 38) | @Override
    method minValue (line 46) | @Override
    method maxValue (line 51) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/PerlinNoise.java
  class PerlinNoise (line 7) | public class PerlinNoise implements Noise {
    method PerlinNoise (line 14) | public PerlinNoise(WorldgenRandom random, double firstOctave, double[]...
    method PerlinNoise (line 18) | public PerlinNoise(WorldgenRandom random, double firstOctave, DoubleLi...
    method sample (line 50) | public double sample(double x, double y, double z) {
    method minValue (line 54) | @Override
    method maxValue (line 59) | @Override
    method sample (line 64) | public double sample(double x, double y, double z, double yScale, doub...
    method getOctaveNoise (line 84) | public ImprovedNoise getOctaveNoise(int i) {
    method edgeValue (line 88) | public double edgeValue(double x) {
    method wrap (line 100) | public static double wrap(double value) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/SimplexNoise.java
  class SimplexNoise (line 5) | public class SimplexNoise implements Noise {
    method SimplexNoise (line 18) | public SimplexNoise(WorldgenRandom random) {
    method sample2D (line 37) | public double sample2D(double x, double z) {
    method floor (line 71) | private static int floor(double x) {
    method sample (line 76) | public double sample(double x, double y, double z) {
    method minValue (line 163) | @Override
    method maxValue (line 168) | @Override
    method get (line 173) | private int get(int i) {
    method getCornerNoise3D (line 177) | private double getCornerNoise3D(int i, double a, double b, double c, d...
    method dot (line 189) | protected static double dot(int[] grad, double a, double b, double c) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/LegacyRandom.java
  class LegacyRandom (line 3) | public class LegacyRandom implements WorldgenRandom {
    method LegacyRandom (line 7) | public LegacyRandom(long seed) {
    method nextLong (line 11) | @Override
    method nextInt (line 18) | @Override
    method nextInt (line 23) | @Override
    method nextDouble (line 44) | @Override
    method fork (line 52) | @Override
    method forkPositional (line 57) | public WorldgenRandom.Positional forkPositional() {
    method next (line 61) | public int next(int max) {
    method fromHashOf (line 69) | @Override
    method fromSeed (line 74) | @Override
    method seedKey (line 79) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/MarsagliaPolarGaussian.java
  class MarsagliaPolarGaussian (line 5) | class MarsagliaPolarGaussian {
    method MarsagliaPolarGaussian (line 10) | public MarsagliaPolarGaussian(WorldgenRandom random) {
    method reset (line 14) | public void reset() {
    method nextGaussian (line 18) | public double nextGaussian() {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/WorldgenRandom.java
  type WorldgenRandom (line 7) | public interface WorldgenRandom extends RandomGenerator {
    method xoroshiro (line 8) | static WorldgenRandom xoroshiro(long seed) {
    method legacy (line 12) | static WorldgenRandom legacy(long i) {
    method nextLong (line 16) | long nextLong();
    method consumeInt (line 18) | default void consumeInt(int i) {
    method consumeLong (line 24) | default void consumeLong(int i) {
    method fork (line 30) | WorldgenRandom fork();
    method forkPositional (line 32) | Positional forkPositional();
    type Positional (line 34) | interface Positional {
      method at (line 36) | default WorldgenRandom at(int x, int y, int z) {
      method fromHashOf (line 40) | WorldgenRandom fromHashOf(String name);
      method fromSeed (line 41) | WorldgenRandom fromSeed(long seed);
      method seedKey (line 43) | long[] seedKey();

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/XoroshiroPositionalRandom.java
  method fromHashOf (line 10) | @Override
  method fromSeed (line 24) | @Override
  method seedKey (line 29) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/XoroshiroRandom.java
  class XoroshiroRandom (line 5) | public class XoroshiroRandom implements WorldgenRandom {
    method XoroshiroRandom (line 9) | public XoroshiroRandom(long seed) {
    method XoroshiroRandom (line 13) | public XoroshiroRandom(Util.Seed seed) {
    method XoroshiroRandom (line 17) | public XoroshiroRandom(long seedLow, long seedHigh) {
    method nextLong (line 21) | @Override
    method nextInt (line 26) | @Override
    method nextInt (line 31) | @Override
    method nextFloat (line 50) | @Override
    method nextDouble (line 55) | @Override
    method nextBits (line 60) | private long nextBits(int bitCount) {
    method fork (line 64) | @Override
    method forkPositional (line 69) | @Override
    class Xoroshiro128PlusPlus (line 74) | private static class Xoroshiro128PlusPlus {
      method Xoroshiro128PlusPlus (line 78) | public Xoroshiro128PlusPlus(long seedLow, long seedHigh) {
      method nextLong (line 87) | public long nextLong() {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorage.java
  type DoubleStorage (line 7) | public interface DoubleStorage {
    method obtain (line 9) | double obtain(int x, int y, int z);
    method from (line 11) | static DoubleStorage from(DensityFunction densityFunction) {
    method cache (line 19) | default DoubleStorage cache() {
    method cache2d (line 27) | default DoubleStorage cache2d() {
    method threadLocal (line 31) | static DoubleStorage threadLocal(Supplier<DoubleStorage> supplier) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorageCache.java
  class DoubleStorageCache (line 6) | class DoubleStorageCache implements DoubleStorage {
    method DoubleStorageCache (line 12) | public DoubleStorageCache(DoubleStorage original) {
    method obtain (line 16) | @Override
    method getIndex (line 22) | private long getIndex(int x, int y, int z) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorageCache2d.java
  class DoubleStorageCache2d (line 7) | class DoubleStorageCache2d implements DoubleStorage {
    method DoubleStorageCache2d (line 11) | public DoubleStorageCache2d(DoubleStorage original) {
    method obtain (line 16) | @Override
    method getIndex (line 21) | private long getIndex(int x, int z) {

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorageThreadLocalImpl.java
  class DoubleStorageThreadLocalImpl (line 5) | class DoubleStorageThreadLocalImpl implements DoubleStorage {
    method DoubleStorageThreadLocalImpl (line 8) | public DoubleStorageThreadLocalImpl(Supplier<DoubleStorage> supplier) {
    method obtain (line 12) | @Override

FILE: datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/util/Util.java
  class Util (line 15) | public class Util {
    method square (line 16) | public static double square(double x) {
    method cube (line 20) | public static double cube(double x) {
    method clamp (line 24) | public static double clamp(double x, double min, double max) {
    method lerp (line 28) | public static double lerp(double a, double b, double c) {
    method lerp2 (line 32) | public static double lerp2(double a, double b, double c, double d, dou...
    method lerp3 (line 36) | public static double lerp3(double a, double b, double c, double d, dou...
    method lazyLerp (line 40) | public static double lazyLerp(double a, DoubleSupplier b, DoubleSuppli...
    method lazyLerp2 (line 47) | public static double lazyLerp2(double a, double b, DoubleSupplier c, D...
    method lazyLerp3 (line 52) | public static double lazyLerp3(double a, double b, double c, DoubleSup...
    method clampedLerp (line 58) | public static double clampedLerp(double a, double b, double c) {
    method inverseLerp (line 68) | public static double inverseLerp(double a, double b, double c) {
    method smoothstep (line 72) | public static double smoothstep(double x) {
    method map (line 76) | public static double map(double a, double b, double c, double d, doubl...
    method clampedMap (line 80) | public static double clampedMap(double a, double b, double c, double d...
    method binarySearch (line 89) | public static int binarySearch(int min, int max, IntPredicate predicat...
    method getSeed (line 100) | public static long getSeed(int x, int y, int z) {
    method longfromBytes (line 106) | public static long longfromBytes(byte a, byte b, byte c, byte d, byte ...
    method jsonRequire (line 117) | public static <T> @NotNull T jsonRequire(JsonObject root, String key, ...
    method jsonArray (line 125) | public static JsonArray jsonArray(JsonElement element) {
    method jsonArray (line 132) | public static <T> List<T> jsonArray(JsonElement element, Function<Json...
    method jsonElse (line 141) | public static <T> @NotNull T jsonElse(JsonObject root, String key, T d...
    method lazy (line 149) | public static <T> Supplier<T> lazy(Supplier<T> supplier) {
    method lazyInt (line 163) | public static IntSupplier lazyInt(IntSupplier supplier) {
    method lazyDouble (line 177) | public static DoubleSupplier lazyDouble(DoubleSupplier supplier) {
    method jsonObject (line 191) | public static JsonObject jsonObject(Object obj) {
    method chunkMinX (line 199) | public static int chunkMinX(Point chunkPos) {
    method chunkMinZ (line 204) | public static int chunkMinZ(Point chunkPos) {
    method chunkMaxX (line 209) | public static int chunkMaxX(Point chunkPos) {
    method chunkMaxZ (line 213) | public static int chunkMaxZ(Point chunkPos) {
    method mixed (line 218) | public Seed mixed() {
    method extract128Seed (line 223) | public static Seed extract128Seed(long originalSeed) {
    method staffordMix13 (line 231) | public static long staffordMix13(long z) {

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/loot/LootTableTestData.java
  class LootTableTestData (line 12) | public class LootTableTestData {

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/loot/LootTableTests.java
  class LootTableTests (line 40) | public class LootTableTests {
    method init (line 47) | @BeforeAll
    method assertItems (line 101) | private void assertItems(String label, List<Item> item, ItemStack... e...
    method assertItems (line 105) | private void assertItems(String label, List<Item> item, List<ItemStack...
    method vanillaLoot (line 125) | @SuppressWarnings("DataFlowIssue")
    method minestomLoot (line 135) | public List<Item> minestomLoot(Map<LootContext.Trait<?>, Object> trait...
    method table (line 150) | private Table table(String src) {
    type Item (line 158) | interface Item {
      method vanilla (line 159) | net.minecraft.world.item.ItemStack vanilla();
      method minestom (line 160) | net.minestom.server.item.ItemStack minestom();
    method item (line 163) | private static Item item(ItemStack minestom) {
    method item (line 172) | private static Item item(net.minecraft.world.item.ItemStack vanilla) {
  method vanilla (line 179) | @Override
  method minestom (line 189) | @Override

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/DF.java
  type DF (line 8) | interface DF {
    method compute (line 9) | double compute(double x, double y, double z);
    method compute (line 12) | @Override
    method vanilla (line 18) | static DF vanilla(String source) {
    method compute (line 26) | @Override
    method vri (line 32) | static DF vri(String source) {
    method createFunctionContext (line 37) | private static net.minecraft.world.level.levelgen.DensityFunction.Func...

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/DFVisualizer.java
  class DFVisualizer (line 9) | public class DFVisualizer {
    type Axis (line 11) | public enum Axis {
    method visualize2d (line 15) | static void visualize2d(String source, double scale, Axis axisToIgnore) {
    method visualize2d (line 19) | static void visualize2d(DF vanilla, DF vri, double scale, Axis axisToS...
    method generateImage (line 76) | private static BufferedImage generateImage(DF df, double scale, Dimens...

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/DensityFunctionTests.java
  class DensityFunctionTests (line 15) | public class DensityFunctionTests {
    method prepare (line 19) | @BeforeAll
    method testEndIslands (line 27) | @Test
    method testConstant (line 32) | @Test
    method testClamp (line 42) | @Test
    method testAbs (line 86) | @Test
    method testSquare (line 96) | @Test
    method testCube (line 112) | @Test
    method testHalfNegative (line 117) | @Test
    method testQuarterNegative (line 127) | @Test
    method testSqueeze (line 137) | @Test
    method testAdd (line 147) | @Test
    method testMul (line 158) | @Test
    method testMin (line 183) | @Test
    method testMax (line 194) | @Test
    method testNoise (line 206) | @Test
    method testPositions (line 223) | private void testPositions(BiConsumer<Vec, Integer> consumer) {
    method assertExact (line 238) | private void assertExact(String source) {
    method assertExact (line 242) | private void assertExact(DF vanilla, DF vri, double delta) {
    method assertEqual (line 251) | public void assertEqual(double delta, Supplier<String> message) {
    method compare (line 256) | private Result compare(DF vanilla, DF vri, int x, int y, int z) {

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/NoiseTests.java
  class NoiseTests (line 12) | public class NoiseTests {
    method testSimplex (line 14) | @Test
    method testSimplex (line 22) | private void testSimplex(long seed) {
    type Noise (line 50) | private interface Noise {
      method sample (line 51) | double sample(double x, double y, double z);
      method sample2d (line 52) | double sample2d(double x, double y);
    method simplexVanilla (line 56) | private static Noise simplexVanilla(long seed) {
    method simplexVri (line 71) | private static Noise simplexVri(long seed) {

FILE: datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/RandomTests.java
  class RandomTests (line 10) | public class RandomTests {
    method testLegacyRandom (line 12) | @Test
    method testLegacyRandom (line 20) | private void testLegacyRandom(long seed) {
    method testXoroshiroRandom (line 44) | @Test

FILE: datapack/src/main/java/net/minestom/vanilla/datapack/Datapacks.java
  class Datapacks (line 38) | @SuppressWarnings("UnstableApiUsage")
    type Type (line 73) | public enum Type {
    method getVersionMetadataURL (line 116) | public static @NotNull URL getVersionMetadataURL(@NotNull String versi...
    method getClientJarURL (line 143) | public static @NotNull URL getClientJarURL(@NotNull URL versionMetadat...
    method downloadJar (line 160) | public static void downloadJar(@NotNull URL sourceUrl, @NotNull Path s...
    method discoverAndDownloadJar (line 198) | public static @NotNull Path discoverAndDownloadJar(@NotNull String ver...
    method ensureCurrentJarExists (line 211) | public static @NotNull Path ensureCurrentJarExists() throws IOException {
    method buildRegistryFromJar (line 215) | @SuppressWarnings("PatternValidation")

FILE: entities/src/main/java/net/minestom/vanilla/entities/FallingBlockEntity.java
  class FallingBlockEntity (line 18) | public class FallingBlockEntity extends Entity {
    method FallingBlockEntity (line 22) | public FallingBlockEntity(@NotNull Block toPlace, @NotNull Pos initial...
    method FallingBlockEntity (line 34) | public FallingBlockEntity(@NotNull VanillaRegistry.EntityContext conte...
    method update (line 38) | @Override

FILE: entities/src/main/java/net/minestom/vanilla/entities/MinestomEntitiesFeature.java
  class MinestomEntitiesFeature (line 8) | public class MinestomEntitiesFeature implements VanillaReimplementation....
    method hook (line 10) | @Override
    method key (line 16) | @Override

FILE: entities/src/main/java/net/minestom/vanilla/entities/PrimedTNTEntity.java
  class PrimedTNTEntity (line 15) | public class PrimedTNTEntity extends Entity {
    method PrimedTNTEntity (line 19) | public PrimedTNTEntity(@NotNull VanillaRegistry.EntityContext context) {
    method PrimedTNTEntity (line 23) | public PrimedTNTEntity(int fuseTime) {
    method explode (line 33) | private void explode() {
    method update (line 46) | @Override
    method getFuseTime (line 54) | public int getFuseTime() {
    method setFuseTime (line 58) | public void setFuseTime(int fuseTime) {

FILE: entity-meta/src/main/java/net/minestom/vanilla/entitymeta/EntityTags.java
  type EntityTags (line 7) | public interface EntityTags {
    type FallingBlock (line 9) | interface FallingBlock {
    type PrimedTnt (line 14) | interface PrimedTnt {

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/EmptyFluid.java
  class EmptyFluid (line 9) | public class EmptyFluid extends Fluid {
    method EmptyFluid (line 11) | public EmptyFluid() {
    method canBeReplacedWith (line 15) | @Override
    method getNextTickDelay (line 20) | @Override
    method isEmpty (line 25) | @Override
    method getBlastResistance (line 30) | @Override
    method getHeight (line 35) | @Override
    method getHeight (line 40) | @Override

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/FlowableFluid.java
  class FlowableFluid (line 18) | public abstract class FlowableFluid extends Fluid {
    method FlowableFluid (line 20) | public FlowableFluid(Block defaultBlock, Material bucket) {
    method onTick (line 24) | @Override
    method getNextTickDelay (line 39) | @Override
    method tryFlow (line 44) | protected void tryFlow(Instance instance, Point point, Block block) {
    method flowSides (line 64) | private void flowSides(Instance instance, Point point, Block block) {
    method getUpdatedState (line 83) | protected Block getUpdatedState(Instance instance, Point point, Block ...
    method receivesFlow (line 121) | private boolean receivesFlow(Direction face, Instance instance, Point ...
    method getID (line 153) | private static short getID(Point point, Point point2) {
    method getSpread (line 164) | protected Map<Direction, Block> getSpread(Instance instance, Point poi...
    method getWeight (line 198) | protected int getWeight(Instance instance, Point point, int initialWei...
    method getAdjacentSourceCount (line 229) | private int getAdjacentSourceCount(Instance instance, Point point) {
    method canFill (line 243) | private boolean canFill(Instance instance, Point point, Block block, B...
    method canFlowDown (line 265) | private boolean canFlowDown(Instance instance, Block flowing, Point po...
    method canFlowThrough (line 272) | private boolean canFlowThrough(Instance instance, Block flowing, Point...
    method canFlow (line 279) | protected boolean canFlow(Instance instance, Point fluidPoint, Block f...
    method flow (line 289) | protected void flow(Instance instance, Point point, Block block, Direc...
    method isMatchingAndStill (line 300) | private boolean isMatchingAndStill(Block block) {
    method getFlowing (line 304) | public Block getFlowing(int level, boolean falling) {
    method getSource (line 308) | public Block getSource(boolean falling) {
    method isInfinite (line 312) | protected abstract boolean isInfinite();
    method getLevelDecreasePerBlock (line 314) | protected abstract int getLevelDecreasePerBlock(Instance instance);
    method getHoleRadius (line 316) | protected abstract int getHoleRadius(Instance instance);
    method onBreakingBlock (line 321) | protected abstract boolean onBreakingBlock(Instance instance, Point po...
    method getTickRate (line 323) | public abstract int getTickRate(Instance instance);
    method isFluidAboveEqual (line 325) | private static boolean isFluidAboveEqual(Block block, Instance instanc...
    method getHeight (line 329) | @Override
    method getHeight (line 334) | @Override

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/Fluid.java
  class Fluid (line 10) | public abstract class Fluid {
    method Fluid (line 14) | public Fluid(Block block, Material bucket) {
    method getDefaultBlock (line 19) | public Block getDefaultBlock() {
    method getBucket (line 23) | public ItemStack getBucket() {
    method canBeReplacedWith (line 27) | protected abstract boolean canBeReplacedWith(Instance instance, Point ...
    method getNextTickDelay (line 30) | public abstract int getNextTickDelay(Instance instance, Point point, B...
    method onTick (line 32) | public void onTick(Instance instance, Point point, Block block) {
    method isEmpty (line 35) | protected boolean isEmpty() {
    method getBlastResistance (line 39) | protected abstract double getBlastResistance();
    method getHeight (line 41) | public abstract double getHeight(Block block, Instance instance, Point...
    method getHeight (line 43) | public abstract double getHeight(Block block);
    method isSource (line 45) | public static boolean isSource(Block block) {
    method getLevel (line 50) | public static int getLevel(Block block) {
    method isFalling (line 58) | public static boolean isFalling(Block block) {

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/FluidPlacementRule.java
  class FluidPlacementRule (line 9) | public class FluidPlacementRule extends BlockPlacementRule {
    method FluidPlacementRule (line 11) | public FluidPlacementRule(@NotNull Block block) {
    method blockPlace (line 15) | @Override

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/FluidSimulationFeature.java
  class FluidSimulationFeature (line 11) | public class FluidSimulationFeature implements VanillaReimplementation.F...
    method hook (line 13) | @Override
    method key (line 19) | @Override
    method dependencies (line 24) | @NotNull

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/MinestomFluids.java
  class MinestomFluids (line 16) | public class MinestomFluids {
    method get (line 22) | public static Fluid get(Block block) {
    method tick (line 32) | public static void tick(InstanceTickEvent event) {
    method tick (line 42) | public static void tick(Instance instance, Point point) {
    method scheduleTick (line 46) | public static void scheduleTick(Instance instance, Point point, Block ...
    method init (line 55) | public static void init(ServerProcess process) {
    method events (line 60) | public static EventNode<Event> events() {

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/WaterBlockBreakEvent.java
  class WaterBlockBreakEvent (line 11) | public class WaterBlockBreakEvent implements InstanceEvent, BlockEvent, ...
    method WaterBlockBreakEvent (line 18) | public WaterBlockBreakEvent(@NotNull Instance instance, @NotNull Block...
    method getInstance (line 24) | @Override
    method getBlockPosition (line 29) | public @NotNull BlockVec getBlockPosition() {
    method getBlock (line 33) | @Override
    method isCancelled (line 38) | @Override
    method setCancelled (line 43) | @Override

FILE: fluid-simulation/src/main/java/io/github/togar2/fluids/WaterFluid.java
  class WaterFluid (line 10) | public class WaterFluid extends FlowableFluid {
    method WaterFluid (line 12) | public WaterFluid() {
    method isInfinite (line 16) | @Override
    method onBreakingBlock (line 21) | @Override
    method getHoleRadius (line 27) | @Override
    method getLevelDecreasePerBlock (line 32) | @Override
    method getTickRate (line 37) | @Override
    method canBeReplacedWith (line 42) | @Override
    method getBlastResistance (line 47) | @Override

FILE: instance-meta/src/main/java/net/minestom/vanilla/instancemeta/InstanceMetaFeature.java
  class InstanceMetaFeature (line 15) | public class InstanceMetaFeature implements VanillaReimplementation.Feat...
    method hook (line 17) | @Override
    method key (line 22) | @Override
    class Logic (line 27) | private static class Logic {
      method Logic (line 32) | private Logic() {
      method hook (line 35) | private void hook(@NotNull VanillaReimplementation vri) {
      method tickInstance (line 40) | private void tickInstance(@NotNull Instance instance) {

FILE: instance-meta/src/main/java/net/minestom/vanilla/instancemeta/tickets/TicketManager.java
  class TicketManager (line 39) | @SuppressWarnings("UnstableApiUsage")
    type Ticket (line 71) | public interface Ticket {
      method value (line 72) | short value();
      method chunk (line 74) | long chunk();
      method from (line 76) | static @NotNull Ticket from(short value, long chunk) {
      method read (line 84) | @Override
      method write (line 94) | @Override
    method TicketManager (line 108) | public TicketManager() {
    method addTicket (line 118) | public void addTicket(@NotNull Ticket ticket) {
    method addTicket (line 128) | public void addTicket(short value, long chunk) {
    method removeTicket (line 202) | public void removeTicket(long chunk, short value) {
    method getTicketValue (line 314) | public short getTicketValue(long chunkIndex) {
    method getChunkInfo (line 324) | public String getChunkInfo(long chunkIndex) {
    method handleInstanceChunkLoad (line 335) | private void handleInstanceChunkLoad(long chunkIndex) {
    method prepareChunk (line 341) | private void prepareChunk(long chunk) {
    class MutableShort (line 346) | private static class MutableShort {
    method recalculateChunkValue (line 350) | private void recalculateChunkValue(long chunkIndex) {

FILE: instance-meta/src/main/java/net/minestom/vanilla/instancemeta/tickets/TicketUtils.java
  class TicketUtils (line 10) | public class TicketUtils {
    method waitingTickets (line 12) | public static @NotNull List<TicketManager.Ticket> waitingTickets(@NotN...
    method waitingTickets (line 16) | public static void waitingTickets(@NotNull Instance instance, @NotNull...
    method removingTickets (line 24) | public static @NotNull List<TicketManager.Ticket> removingTickets(Inst...
    method removingTickets (line 28) | public static void removingTickets(Instance instance, @NotNull Collect...

FILE: item-placeables/src/main/java/net/minestom/vanilla/itemplaceables/ItemPlaceablesFeature.java
  class ItemPlaceablesFeature (line 15) | public class ItemPlaceablesFeature implements VanillaReimplementation.Fe...
    method hook (line 16) | @Override
    method key (line 38) | @Override

FILE: items/src/main/java/net/minestom/vanilla/items/FlintAndSteelHandler.java
  class FlintAndSteelHandler (line 14) | public class FlintAndSteelHandler implements VanillaItemHandler {
    method FlintAndSteelHandler (line 15) | public FlintAndSteelHandler() {
    method onUseOnBlock (line 18) | @Override

FILE: items/src/main/java/net/minestom/vanilla/items/ItemManager.java
  class ItemManager (line 16) | public class ItemManager {
    method accumulate (line 18) | public static @NotNull ItemManager accumulate(@NotNull Consumer<Accumu...
    type Accumulator (line 24) | public interface Accumulator {
      method accumulate (line 25) | void accumulate(@NotNull Material material, @NotNull VanillaItemHand...
    method ItemManager (line 30) | private ItemManager(Map<Material, VanillaItemHandler> itemHandlersByMa...
    method handlePlayerUseItemEvent (line 34) | private void handlePlayerUseItemEvent(PlayerUseItemEvent event) {
    method handlePlayerUseItemOnBlockEvent (line 46) | private void handlePlayerUseItemOnBlockEvent(PlayerUseItemOnBlockEvent...
    method registerEvents (line 58) | public void registerEvents(EventNode<Event> itemEventNode) {

FILE: items/src/main/java/net/minestom/vanilla/items/ItemsFeature.java
  class ItemsFeature (line 8) | public class ItemsFeature implements VanillaReimplementation.Feature {
    method hook (line 10) | @Override
    method key (line 20) | @Override

FILE: items/src/main/java/net/minestom/vanilla/items/VanillaItemHandler.java
  type VanillaItemHandler (line 6) | public interface VanillaItemHandler {
    method onUseInAir (line 13) | default void onUseInAir(PlayerUseItemEvent event) {
    method onUseOnBlock (line 22) | default boolean onUseOnBlock(PlayerUseItemOnBlockEvent event) {

FILE: items/src/main/java/net/minestom/vanilla/items/VanillaItems.java
  type VanillaItems (line 11) | public enum VanillaItems {
    method VanillaItems (line 18) | VanillaItems(@NotNull Material material, Supplier<VanillaItemHandler> ...
    method getMaterial (line 23) | public @NotNull Material getMaterial() {
    method getItemHandlerSupplier (line 27) | public @NotNull Supplier<VanillaItemHandler> getItemHandlerSupplier() {

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/BlockExperience.java
  class BlockExperience (line 18) | public class BlockExperience {
    method getExperience (line 23) | public static int getExperience(@NotNull Block minedBlock, @NotNull It...
    type Amount (line 38) | public sealed interface Amount {
    method entry (line 73) | private static Map.Entry<Integer, Amount> entry(Block block, Amount am...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootContext.java
  type LootContext (line 21) | public sealed interface LootContext permits LootContextImpl {
    method from (line 43) | static @NotNull LootContext from(@NotNull Map<Key<?>, Object> data) {
    method key (line 50) | static <T> LootContext.@NotNull Key<T> key(@NotNull String key) {
    method has (line 67) | boolean has(@NotNull Key<?> key);
    method get (line 75) | <T> @Nullable T get(@NotNull Key<T> key);
    method get (line 84) | <T> @NotNull T get(@NotNull Key<T> key, @NotNull T defaultValue);
    method require (line 92) | <T> @NotNull T require(@NotNull Key<T> key);
  method from (line 102) | static @NotNull LootContext from(@NotNull Map<Key<?>, Object> data) {
  method has (line 113) | @Override
  method get (line 118) | @SuppressWarnings("unchecked")
  method get (line 124) | @Override
  method require (line 130) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootEntry.java
  type LootEntry (line 24) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 28) | class Holder {
    method createDefaultRegistry (line 34) | static @NotNull DynamicRegistry<StructCodec<? extends LootEntry>> crea...
    method requestChoices (line 52) | @NotNull List<Choice> requestChoices(@NotNull LootContext context);
    method codec (line 57) | @NotNull StructCodec<? extends LootEntry> codec();
    type Choice (line 62) | interface Choice extends LootGenerator {
      method getWeight (line 72) | @Range(from = 1L, to = Long.MAX_VALUE) long getWeight(@NotNull LootC...
      type Standard (line 79) | interface Standard extends Choice {
        method weight (line 85) | @Range(from = 1L, to = Long.MAX_VALUE) long weight();
        method quality (line 92) | @Range(from = 0L, to = Long.MAX_VALUE) long quality();
        method getWeight (line 94) | @Override
      type Single (line 104) | interface Single extends LootEntry, LootEntry.Choice, Standard {
        method predicates (line 109) | @NotNull List<LootPredicate> predicates();
        method requestChoices (line 115) | @Override
    method requestChoices (line 131) | @Override
    method codec (line 144) | @Override
    method generate (line 168) | @Override
    method codec (line 186) | @Override
    method generate (line 202) | @Override
    method codec (line 207) | @Override
    method requestChoices (line 220) | @Override
    method codec (line 231) | @Override
    method generate (line 248) | @Override
    method codec (line 253) | @Override
    method generate (line 270) | @Override
    method codec (line 282) | @Override
    method requestChoices (line 295) | @Override
    method codec (line 310) | @Override
    method requestChoices (line 328) | @Override
    method generate (line 359) | @Override
    method codec (line 373) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootFeature.java
  class LootFeature (line 32) | public class LootFeature {
    method buildFromDatapack (line 34) | public static @NotNull Map<Key, LootTable> buildFromDatapack(@NotNull ...
    method createEventNode (line 51) | @SuppressWarnings("PatternValidation")
    method blockDrop (line 97) | public static void blockDrop(@NotNull Instance instance, @NotNull Item...
    method drop (line 111) | public static void drop(@NotNull Instance instance, @NotNull ItemStack...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootFunction.java
  type LootFunction (line 52) | @SuppressWarnings("UnstableApiUsage")
    method makeCodec (line 57) | private static StructCodec<LootFunction> makeCodec() {
    method createDefaultRegistry (line 66) | static @NotNull DynamicRegistry<StructCodec<? extends LootFunction>> c...
    method apply (line 117) | @NotNull ItemStack apply(@NotNull ItemStack input, @NotNull LootContex...
    method codec (line 122) | @NotNull StructCodec<? extends LootFunction> codec();
    method apply (line 131) | static @NotNull ItemStack apply(@NotNull Collection<LootFunction> func...
    method apply (line 145) | static @NotNull List<ItemStack> apply(@NotNull Collection<LootFunction...
    type Formula (line 161) | public sealed interface Formula {
      type FormulaType (line 163) | enum FormulaType {
      method wrap (line 170) | @SuppressWarnings("unchecked")
      method decodeFromMap (line 180) | @Override
      method encodeToMap (line 185) | @Override
      method codec (line 192) | public static @NotNull StructCodec<Wrapper> codec(@NotNull FormulaTy...
      method calculate (line 212) | int calculate(@NotNull Random random, int count, int level);
      method calculate (line 220) | @Override
      method calculate (line 229) | @Override
      method calculate (line 244) | @Override
    method apply (line 258) | @Override
    method codec (line 269) | @Override
    method apply (line 285) | @Override
    method codec (line 293) | @Override
    method execute (line 315) | public void execute(@NotNull NBTReference nbt, @NotNull BinaryTag sour...
    type Operator (line 324) | public enum Operator {
      method merge (line 326) | @Override
      method merge (line 332) | @Override
      method merge (line 342) | @Override
      method merge (line 360) | public abstract void merge(@NotNull NBTReference nbt, @NotNull NBTPa...
    method apply (line 363) | @Override
    method codec (line 383) | @Override
    method apply (line 398) | @Override
    method codec (line 416) | @Override
    method apply (line 436) | @Override
    method codec (line 457) | @Override
    method apply (line 473) | @Override
    method codec (line 487) | @Override
    method apply (line 501) | @Override
    method codec (line 523) | @Override
    method apply (line 537) | @Override
    method codec (line 545) | @Override
    method apply (line 557) | @Override
    method codec (line 565) | @Override
    method apply (line 577) | @Override
    method codec (line 600) | @Override
    method apply (line 613) | @Override
    method codec (line 627) | @Override
    method apply (line 641) | @Override
    method codec (line 647) | @Override
    method apply (line 659) | @Override
    method codec (line 669) | @Override
    method apply (line 682) | @Override
    method codec (line 688) | @Override
    method apply (line 709) | @Override
    method codec (line 724) | @Override
    method apply (line 737) | @Override
    method codec (line 747) | @Override
    method apply (line 785) | @Override
    method codec (line 821) | @Override
    method apply (line 835) | @Override
    method codec (line 851) | @Override
    method apply (line 867) | @Override
    method codec (line 884) | @Override
    method apply (line 897) | @Override
    method constantGeneric (line 911) | @SuppressWarnings("unchecked")
    method codec (line 916) | @Override
    method apply (line 931) | @Override
    method codec (line 946) | @Override
    method apply (line 960) | @Override
    method codec (line 966) | @Override
    method apply (line 979) | @Override
    method codec (line 986) | @Override
    method apply (line 999) | @Override
    method codec (line 1008) | @Override
    method apply (line 1022) | @Override
    method codec (line 1039) | @Override
    method apply (line 1053) | @Override
    method codec (line 1068) | @Override
    method apply (line 1089) | @Override
    method codec (line 1106) | @Override
    method apply (line 1120) | @Override
    method codec (line 1134) | @Override
    method apply (line 1147) | @Override
    method codec (line 1162) | @Override
    method apply (line 1175) | @Override
    method codec (line 1182) | @Override
    method apply (line 1196) | @Override
    method codec (line 1204) | @Override
    method apply (line 1220) | @Override
    method codec (line 1233) | @Override
    type Target (line 1249) | public enum Target {
      method Target (line 1258) | Target(String id, DataComponent<Component> component) {
      method id (line 1263) | public String id() {
      method component (line 1267) | public DataComponent<Component> component() {
    method apply (line 1272) | @Override
    method codec (line 1286) | @Override
    method apply (line 1299) | @Override
    method codec (line 1308) | @Override
    method apply (line 1321) | @Override
    method codec (line 1335) | @Override
    method apply (line 1356) | @Override
    method codec (line 1375) | @Override
    method apply (line 1389) | @Override
    method codec (line 1398) | @Override
    method apply (line 1412) | @Override
    method codec (line 1422) | @Override
    method apply (line 1434) | @Override
    method codec (line 1439) | @Override
    method apply (line 1452) | @Override
    method codec (line 1465) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootGenerator.java
  type LootGenerator (line 11) | public interface LootGenerator {
    method generate (line 13) | @NotNull List<ItemStack> generate(@NotNull LootContext context);

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootNBT.java
  type LootNBT (line 22) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 26) | class Holder {
    method createDefaultRegistry (line 35) | static @NotNull DynamicRegistry<StructCodec<? extends LootNBT>> create...
    method getNBT (line 47) | @Nullable BinaryTag getNBT(@NotNull LootContext context);
    method codec (line 52) | @NotNull StructCodec<? extends LootNBT> codec();
    method getNBT (line 60) | @Override
    method codec (line 67) | @Override
    type Target (line 79) | public sealed interface Target {
      method getNBT (line 80) | @Nullable BinaryTag getNBT(@NotNull LootContext context);
      method fromString (line 82) | static @NotNull Target fromString(@NotNull String input) {
      method getNBT (line 93) | @SuppressWarnings("DataFlowIssue")
      method toString (line 109) | @Override
      method getNBT (line 116) | @Override
      method toString (line 124) | @Override
    method getNBT (line 131) | @Override
    method codec (line 136) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootNumber.java
  type LootNumber (line 21) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 25) | class Holder {
    method createDefaultRegistry (line 31) | static @NotNull DynamicRegistry<StructCodec<? extends LootNumber>> cre...
    method getInt (line 48) | int getInt(@NotNull LootContext context);
    method getDouble (line 56) | double getDouble(@NotNull LootContext context);
    method codec (line 61) | @NotNull StructCodec<? extends LootNumber> codec();
    method getInt (line 70) | @Override
    method getDouble (line 85) | @Override
    method codec (line 90) | @Override
    method getInt (line 102) | @Override
    method getDouble (line 107) | @Override
    method codec (line 112) | @Override
    method getInt (line 124) | @Override
    method getDouble (line 129) | @Override
    method codec (line 134) | @Override
    method getInt (line 148) | @Override
    method getDouble (line 153) | @Override
    method codec (line 160) | @Override
    method getInt (line 173) | @Override
    method getDouble (line 178) | @Override
    method get (line 183) | private NumberBinaryTag get(@NotNull LootContext context) {
    method codec (line 197) | @Override
    method getInt (line 210) | @Override
    method getDouble (line 215) | @Override
    method codec (line 220) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootPool.java
  method generate (line 35) | @Override
  method pickChoice (line 65) | static @Nullable LootEntry.Choice pickChoice(@NotNull List<LootEntry> en...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootPredicate.java
  type LootPredicate (line 36) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 40) | class Holder {
    method createDefaultRegistry (line 46) | static @NotNull DynamicRegistry<StructCodec<? extends LootPredicate>> ...
    method test (line 75) | @Override
    method codec (line 81) | @NotNull StructCodec<? extends LootPredicate> codec();
    method all (line 86) | static boolean all(@NotNull List<LootPredicate> predicates, @NotNull L...
    method test (line 104) | @Override
    method codec (line 109) | @Override
    method test (line 121) | @Override
    method codec (line 134) | @Override
    method test (line 147) | @Override
    method codec (line 154) | @Override
    method test (line 166) | @Override
    method codec (line 179) | @Override
    method test (line 191) | @Override
    method codec (line 196) | @Override
    method test (line 209) | @Override
    method codec (line 217) | @Override
    method test (line 230) | @Override
    method codec (line 246) | @Override
    method test (line 258) | @Override
    method codec (line 263) | @Override
    method test (line 272) | @Override
    method codec (line 277) | @Override
    method test (line 292) | @Override
    method codec (line 302) | @Override
    method test (line 314) | @Override
    method codec (line 324) | @Override
    method test (line 336) | @Override
    method codec (line 341) | @Override
    method test (line 355) | @Override
    method codec (line 365) | @Override
    method test (line 377) | @Override
    method codec (line 385) | @Override
    method test (line 394) | @Override
    method codec (line 400) | @Override
    method test (line 413) | @Override
    method codec (line 424) | @Override
    method test (line 437) | @Override
    method codec (line 448) | @Override
    method test (line 461) | @Override
    method codec (line 466) | @Override
    method test (line 479) | @Override
    method codec (line 487) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootScore.java
  type LootScore (line 16) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 20) | class Holder {
    method createDefaultRegistry (line 26) | static @NotNull DynamicRegistry<StructCodec<? extends LootScore>> crea...
    method apply (line 33) | @Override
    method codec (line 39) | @NotNull StructCodec<? extends LootScore> codec();
    method apply (line 47) | @Override
    method codec (line 52) | @Override
    method apply (line 64) | @Override
    method codec (line 69) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/LootTable.java
  method generate (line 31) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/EnchantmentUtils.java
  class EnchantmentUtils (line 20) | public class EnchantmentUtils {
    method EnchantmentUtils (line 22) | private EnchantmentUtils() {
    method level (line 25) | public static int level(@Nullable ItemStack item, @NotNull RegistryKey...
    method level (line 34) | public static int level(@Nullable Entity entity, @NotNull RegistryKey<...
    method modifyItem (line 48) | public static @NotNull ItemStack modifyItem(@NotNull ItemStack item, @...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/ListOperation.java
  type ListOperation (line 14) | @SuppressWarnings("UnstableApiUsage")
    class Holder (line 18) | class Holder {
    method createDefaultRegistry (line 24) | static @NotNull DynamicRegistry<StructCodec<? extends ListOperation>> ...
    method apply (line 33) | <T> @NotNull List<T> apply(@NotNull List<T> values, @NotNull List<T> i...
    method codec (line 38) | @NotNull StructCodec<? extends ListOperation> codec();
    method codec (line 41) | public static <T> Codec<WithValues<T>> codec(Codec<T> codec) {
    method apply (line 53) | @Override
    method codec (line 58) | @Override
    method apply (line 70) | @Override
    method codec (line 79) | @Override
    method apply (line 88) | @Override
    method codec (line 93) | @Override
    method apply (line 106) | @Override
    method codec (line 122) | @Override

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/LootNumberRange.java
  method limit (line 37) | public long limit(@NotNull LootContext context, long number) {
  method limit (line 55) | public double limit(@NotNull LootContext context, double number) {
  method check (line 72) | public boolean check(@NotNull LootContext context, long number) {
  method check (line 84) | public boolean check(@NotNull LootContext context, double number) {

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/RelevantEntity.java
  type RelevantEntity (line 8) | public enum RelevantEntity {
    method RelevantEntity (line 20) | RelevantEntity(@NotNull String id, @NotNull LootContext.Key<? extends ...
    method id (line 25) | public @NotNull String id() {
    method key (line 29) | public @NotNull LootContext.Key<? extends Entity> key() {

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/RelevantTarget.java
  type RelevantTarget (line 7) | public enum RelevantTarget {
    method RelevantTarget (line 19) | RelevantTarget(@NotNull String id, @NotNull LootContext.Key<?> key) {
    method id (line 24) | public @NotNull String id() {
    method key (line 28) | public @NotNull LootContext.Key<?> key() {

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/nbt/NBTPath.java
  type Selector (line 33) | public sealed interface Selector {
    method get (line 38) | void get(@NotNull NBTReference source, @NotNull Consumer<NBTReference>...
    method prepare (line 44) | void prepare(@NotNull NBTReference source, @NotNull Supplier<BinaryTag...
    method preparedNBT (line 49) | @NotNull BinaryTag preparedNBT();
    method get (line 52) | @Override
    method prepare (line 59) | @Override
    method preparedNBT (line 62) | @Override
    method toString (line 67) | @Override
    method get (line 74) | @Override
    method prepare (line 81) | @Override
    method preparedNBT (line 88) | @Override
    method toString (line 93) | @Override
    method get (line 100) | @Override
    method prepare (line 107) | @Override
    method preparedNBT (line 114) | @Override
    method toString (line 119) | @Override
    method get (line 130) | @Override
    method prepare (line 138) | @Override
    method preparedNBT (line 145) | @Override
    method toString (line 150) | @Override
    method get (line 157) | @Override
    method prepare (line 166) | @Override
    method preparedNBT (line 169) | @Override
    method toString (line 174) | @Override
    method get (line 181) | @Override
    method prepare (line 192) | @Override
    method preparedNBT (line 206) | @Override
    method toString (line 211) | @Override
  method get (line 229) | public @NotNull List<NBTReference> get(@NotNull BinaryTag source) {
  method getWithDefaults (line 253) | public @NotNull List<NBTReference> getWithDefaults(@NotNull NBTReference...
  method set (line 285) | public @NotNull List<NBTReference> set(@NotNull NBTReference source, @No...
  method toString (line 293) | @Override
  class Parser (line 299) | @SuppressWarnings("UnstableApiUsage")
    method readPath (line 314) | static @NotNull NBTPath readPath(@NotNull StringReader reader) throws ...
    method readPathSelector (line 344) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method readInteger (line 384) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method readString (line 403) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method peek (line 450) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method readTag (line 457) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method readCompound (line 478) | private static CompoundBinaryTag readCompound(@NotNull StringReader re...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/nbt/NBTReference.java
  method of (line 15) | public static @NotNull NBTReference of(@NotNull BinaryTag tag) {
  method get (line 20) | public BinaryTag get() {
  method set (line 24) | public void set(BinaryTag nbt) {
  method has (line 28) | public boolean has(@NotNull String key) {
  method get (line 32) | public NBTReference get(@NotNull String key) {
  method listSize (line 43) | public int listSize() {
  method get (line 47) | public @NotNull NBTReference get(int index) {
  method listAdd (line 60) | public void listAdd(@NotNull BinaryTag tag) {

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/nbt/NBTUtils.java
  class NBTUtils (line 11) | public class NBTUtils {
    method NBTUtils (line 13) | private NBTUtils() {}
    method compareNBT (line 26) | public static boolean compareNBT(@Nullable BinaryTag standard, @Nullab...
    method merge (line 75) | public static CompoundBinaryTag merge(@NotNull CompoundBinaryTag base,...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/predicate/DamageSourcePredicate.java
  type DamageSourcePredicate (line 12) | @SuppressWarnings("UnstableApiUsage")
    method test (line 17) | boolean test(@NotNull Instance instance, @NotNull Point pos, @NotNull ...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/predicate/EntityPredicate.java
  type EntityPredicate (line 13) | @SuppressWarnings("UnstableApiUsage")
    method test (line 18) | boolean test(@NotNull Instance instance, @Nullable Point pos, @Nullabl...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/predicate/ItemPredicate.java
  method test (line 24) | public boolean test(@NotNull ItemStack itemStack, @NotNull LootContext c...

FILE: loot-table/src/main/java/net/minestom/vanilla/loot/util/predicate/LocationPredicate.java
  type LocationPredicate (line 11) | @SuppressWarnings("UnstableApiUsage")
    method test (line 16) | boolean test(@NotNull Instance instance, @NotNull Point point);

FILE: mojang-data/src/main/java/io/github/pesto/MojangAssets.java
  class MojangAssets (line 24) | final class MojangAssets {
    method getAssets (line 28) | public CompletableFuture<FileSystem<ByteArray>> getAssets(@NotNull Str...
    method downloadResources (line 32) | private FileSystem<ByteArray> downloadResources(@NotNull String versio...
    method findVersionInfoUrl (line 65) | private String findVersionInfoUrl(@NotNull String version) throws IOEx...
    method downloadJar (line 94) | private void downloadJar(JsonObject versionInfo, @NotNull File destina...
    method downloadJson (line 179) | private JsonObject downloadJson(String url) throws IOException {
    method getDownloadStream (line 183) | private InputStream getDownloadStream(String url) throws IOException {
    method exitError (line 187) | private void exitError(String message) {

FILE: mojang-data/src/main/java/io/github/pesto/MojangDataFeature.java
  class MojangDataFeature (line 11) | public class MojangDataFeature implements VanillaReimplementation.Feature {
    method hook (line 17) | @Override
    method key (line 24) | @Override
    method latestAssets (line 29) | public FileSystem<ByteArray> latestAssets() {
    method assetsRequest (line 36) | public CompletableFuture<FileSystem<ByteArray>> assetsRequest(@NotNull...

FILE: server/src/main/java/net/minestom/vanilla/server/VanillaDebug.java
  class VanillaDebug (line 21) | public class VanillaDebug {
    method hook (line 22) | public static void hook(VanillaServer server) {
    method handleMessage (line 34) | private static void handleMessage(VanillaServer server, Player player,...

FILE: server/src/main/java/net/minestom/vanilla/server/VanillaEvents.java
  class VanillaEvents (line 34) | public class VanillaEvents {
    method register (line 36) | public static void register(VanillaServer server, ServerProperties pro...

FILE: server/src/main/java/net/minestom/vanilla/server/VanillaServer.java
  class VanillaServer (line 29) | class VanillaServer {
    method main (line 36) | public static void main(String[] args) {
    method VanillaServer (line 60) | public VanillaServer(@NotNull MinecraftServer minecraftServer, @NotNul...
    method getOrGenerateServerProperties (line 143) | private ServerProperties getOrGenerateServerProperties() {
    method start (line 205) | public void start(String address, int port) {
    method vri (line 209) | public VanillaReimplementation vri() {
    method overworld (line 213) | public Instance overworld() {

FILE: survival/src/main/java/net/minestom/vanilla/survival/Survival.java
  class Survival (line 40) | public class Survival {
    method main (line 41) | public static void main(String[] args) {
    method Survival (line 55) | Survival(@NotNull ServerProcess process) {
    method initialize (line 69) | public void initialize() {
    method broadcast (line 123) | private void broadcast(@NotNull Component message) {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/Aquifer.java
  type Aquifer (line 16) | public interface Aquifer {
    method compute (line 18) | @Nullable Block compute(DensityFunction.Context context, double density);
    method at (line 21) | public Block at(int level) {
    type FluidPicker (line 26) | interface FluidPicker {
      method pickFluid (line 27) | FluidStatus pickFluid(int x, int y, int z);
    method createDisabled (line 30) | static Aquifer createDisabled(FluidPicker fluidPicker) {
    class NoiseAquifer (line 39) | class NoiseAquifer implements Aquifer {
      method NoiseAquifer (line 66) | public NoiseAquifer(
      method compute (line 89) | public Block compute(DensityFunction.Context context, double density) {
      method similarity (line 160) | private static double similarity(double a, double b) {
      method calculatePressure (line 164) | private double calculatePressure(int y, FluidStatus status1, FluidSt...
      method getStatus (line 186) | private FluidStatus getStatus(DensityFunction.Context context, Point...
      method computeStatus (line 200) | private FluidStatus computeStatus(DensityFunction.Context context, i...
      method getFluidType (line 244) | private Block getFluidType(DensityFunction.Context context, double x...
      method getLocation (line 254) | private Point getLocation(int x, int y, int z) {
      method getIndex (line 269) | private int getIndex(int x, int y, int z) {
      method gridX (line 280) | private int gridX(int x) {
      method gridY (line 284) | private int gridY(int y) {
      method gridZ (line 288) | private int gridZ(int z) {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/NoiseChunk.java
  class NoiseChunk (line 16) | public class NoiseChunk {
    method NoiseChunk (line 37) | public NoiseChunk(
    method getFinalState (line 70) | public @Nullable Block getFinalState(Datapack datapack, int x, int y, ...
    method getPreliminarySurfaceLevel (line 74) | public int getPreliminarySurfaceLevel(int quartX, int quartZ) {
    type MaterialRule (line 88) | public interface MaterialRule {
      method compute (line 89) | @Nullable Block compute(DensityFunction.Context context);
      method fromList (line 91) | static MaterialRule fromList(List<MaterialRule> rules) {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/NoiseChunkGenerator.java
  class NoiseChunkGenerator (line 21) | public class NoiseChunkGenerator {
    method NoiseChunkGenerator (line 49) | public NoiseChunkGenerator(@NotNull Datapack datapack, @NotNull BiomeS...
    method fill (line 81) | public void fill(Datapack datapack, RandomState randomState, TargetChu...
    method fill (line 85) | public void fill(Datapack datapack, RandomState randomState, TargetChu...
    method buildSurface (line 131) | public void buildSurface(Datapack datapack, RandomState randomState, T...
    method computeBiome (line 137) | public Key computeBiome(RandomState randomState, int quartX, int quart...
    method getOrCreateNoiseChunk (line 141) | private NoiseChunk getOrCreateNoiseChunk(RandomState randomState, Targ...
    method generateChunkData (line 172) | public synchronized void generateChunkData(@NotNull ChunkBatch batch, ...
    class TargetChunkImpl (line 181) | private static class TargetChunkImpl implements TargetChunk {
      method TargetChunkImpl (line 193) | public TargetChunkImpl(ChunkBatch batch, int chunkX, int chunkZ, int...
      method chunkX (line 201) | @Override
      method chunkZ (line 206) | @Override
      method minSection (line 211) | @Override
      method maxSection (line 216) | @Override
      method getBlock (line 221) | @Override
      method setBlock (line 227) | @Override
    type TargetChunk (line 238) | public interface TargetChunk extends Block.Getter, Block.Setter {
      method chunkX (line 239) | int chunkX();
      method chunkZ (line 241) | int chunkZ();
      method minX (line 243) | default int minX() {
      method maxX (line 247) | default int maxX() {
      method minZ (line 251) | default int minZ() {
      method maxZ (line 255) | default int maxZ() {
      method index (line 259) | default long index() {
      method minSection (line 263) | int minSection();
      method maxSection (line 265) | int maxSection();
      method minY (line 267) | default int minY() {
      method maxY (line 271) | default int maxY() {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/RandomState.java
  class RandomState (line 11) | public class RandomState {
    method RandomState (line 22) | public RandomState(NoiseSettings settings, long seed) {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/SurfaceContext.java
  class SurfaceContext (line 17) | public class SurfaceContext implements NoiseSettings.SurfaceRule.Context {
    method SurfaceContext (line 36) | public SurfaceContext(SurfaceSystem system, NoiseChunkGenerator.Target...
    method updateXZ (line 45) | public void updateXZ(int x, int z) {
    method updateY (line 53) | public void updateY(int stoneDepthAbove, int stoneDepthBelow, int wate...
    method calculateMinSurfaceLevel (line 61) | private int calculateMinSurfaceLevel(int x, int z) {
    method asDFContext (line 72) | private DensityFunction.Context asDFContext() {
    method biome (line 76) | @Override
    method minY (line 81) | @Override
    method maxY (line 86) | @Override
    method blockX (line 91) | @Override
    method blockY (line 96) | @Override
    method blockZ (line 101) | @Override
    method random (line 106) | @Override
    method stoneDepthAbove (line 111) | @Override
    method surfaceDepth (line 116) | @Override
    method waterHeight (line 121) | @Override
    method minSurfaceLevel (line 126) | @Override
    method stoneDepthBelow (line 131) | @Override
    method surfaceSecondary (line 136) | @Override

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/SurfaceSystem.java
  class SurfaceSystem (line 19) | public class SurfaceSystem {
    method SurfaceSystem (line 28) | public SurfaceSystem(NoiseSettings.SurfaceRule rule, Block defaultBloc...
    method buildSurface (line 37) | public void buildSurface(NoiseChunkGenerator.TargetChunk chunk, NoiseC...
    method getSurfaceDepth (line 94) | public int getSurfaceDepth(double x, double z) {
    method getSurfaceSecondary (line 100) | public double getSurfaceSecondary(double x, double z) {
    method getRandom (line 104) | public WorldgenRandom getRandom(String name) {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/VanillaTestGenerator.java
  class VanillaTestGenerator (line 14) | public class VanillaTestGenerator implements Generator {
    method noise (line 25) | private synchronized double noise(JNoise noise, double x, double z) {
    method generate (line 29) | @Override
    method spawnTree (line 76) | private void spawnTree(Block.Setter setter, Point pos) {

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/VanillaWorldGenerationFeature.java
  class VanillaWorldGenerationFeature (line 13) | public class VanillaWorldGenerationFeature implements VanillaReimplement...
    method hook (line 15) | @Override
    method key (line 46) | @Override
    method dependencies (line 51) | @Override

FILE: world-generation/src/main/java/net/minestom/vanilla/generation/VanillaWorldgen.java
  class VanillaWorldgen (line 3) | public final class VanillaWorldgen {
Condensed preview — 263 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,267K chars).
[
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 1556,
    "preview": "## How to contribute to Vanilla Reimplementation\n\n#### **Did you find a bug?**\n\n* Ensure that the associated system is i"
  },
  {
    "path": ".gitignore",
    "chars": 566,
    "preview": "# Created by .ignore support plugin (hsz.mobi)\n### Java template\n# Compiled class file\n*.class\n*/build/*\nbuild/*\n\n# Log "
  },
  {
    "path": ".gitmodules",
    "chars": 337,
    "preview": "[submodule \"vanilla_worldgen_example\"]\n\tpath = vanilla_worldgen_example\n\turl = https://github.com/slicedlime/examples/\n["
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 1269,
    "preview": "# NOT READY FOR PRODUCTION\n\nPriority is currently on the core of Minestom (see below). This project has only a very limi"
  },
  {
    "path": "block-update-system/build.gradle.kts",
    "chars": 50,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n}"
  },
  {
    "path": "block-update-system/src/main/java/net/minestom/vanilla/BlockUpdateFeature.java",
    "chars": 763,
    "preview": "package net.minestom.vanilla;\n\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.vanilla.blockupdatesystem.BlockU"
  },
  {
    "path": "block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdatable.java",
    "chars": 424,
    "preview": "package net.minestom.vanilla.blockupdatesystem;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server"
  },
  {
    "path": "block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdateInfo.java",
    "chars": 638,
    "preview": "package net.minestom.vanilla.blockupdatesystem;\n\npublic interface BlockUpdateInfo {\n\n    static DestroyBlock DESTROY_BLO"
  },
  {
    "path": "block-update-system/src/main/java/net/minestom/vanilla/blockupdatesystem/BlockUpdateManager.java",
    "chars": 6251,
    "preview": "package net.minestom.vanilla.blockupdatesystem;\n\nimport it.unimi.dsi.fastutil.shorts.Short2ObjectMap;\nimport it.unimi.ds"
  },
  {
    "path": "block-update-system/src/main/java/net/minestom/vanilla/randomticksystem/RandomTickManager.java",
    "chars": 3583,
    "preview": "package net.minestom.vanilla.randomticksystem;\n\nimport it.unimi.dsi.fastutil.shorts.Short2ObjectMap;\nimport it.unimi.dsi"
  },
  {
    "path": "block-update-system/src/main/java/net/minestom/vanilla/randomticksystem/RandomTickable.java",
    "chars": 460,
    "preview": "package net.minestom.vanilla.randomticksystem;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server."
  },
  {
    "path": "blocks/build.gradle.kts",
    "chars": 186,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n    compileOnly(project(\":block-update-system\"))\n    compileOnly(projec"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlockBehaviour.java",
    "chars": 1957,
    "preview": "package net.minestom.vanilla.blocks;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.coordinate.Point;\ni"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlockLoot.java",
    "chars": 8765,
    "preview": "package net.minestom.vanilla.blocks;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server.entity.Ite"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlocks.java",
    "chars": 17702,
    "preview": "package net.minestom.vanilla.blocks;\n\nimport it.unimi.dsi.fastutil.shorts.Short2ObjectMap;\nimport it.unimi.dsi.fastutil."
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/VanillaBlocksFeature.java",
    "chars": 2512,
    "preview": "package net.minestom.vanilla.blocks;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.coordinate.Point;\ni"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/BedBlockBehaviour.java",
    "chars": 5222,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server."
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/CakeBlockBehaviour.java",
    "chars": 3775,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/ChestBlockBehaviour.java",
    "chars": 553,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.server.i"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/ConcretePowderBlockBehaviour.java",
    "chars": 1884,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/EndPortalBlockBehaviour.java",
    "chars": 3388,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server."
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/EnderChestBlockBehaviour.java",
    "chars": 997,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.server.c"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/FireBlockBehaviour.java",
    "chars": 1787,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/GravityBlockBehaviour.java",
    "chars": 2657,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/InventoryBlockBehaviour.java",
    "chars": 8287,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.server.c"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/JukeboxBlockBehaviour.java",
    "chars": 6513,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server."
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/NetherPortalBlockBehaviour.java",
    "chars": 12722,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server."
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/TNTBlockBehaviour.java",
    "chars": 2440,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/TrappedChestBlockBehaviour.java",
    "chars": 780,
    "preview": "package net.minestom.vanilla.blocks.behaviours;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.server.i"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/BlockInventory.java",
    "chars": 2445,
    "preview": "package net.minestom.vanilla.blocks.behaviours.chestlike;\n\nimport net.kyori.adventure.text.Component;\nimport net.minesto"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/BlockItems.java",
    "chars": 3162,
    "preview": "package net.minestom.vanilla.blocks.behaviours.chestlike;\n\nimport net.minestom.server.instance.block.Block;\nimport net.m"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/chestlike/DoubleChestInventory.java",
    "chars": 1536,
    "preview": "package net.minestom.vanilla.blocks.behaviours.chestlike;\n\nimport net.minestom.server.inventory.Inventory;\nimport net.mi"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxidatableBlockBehaviour.java",
    "chars": 8271,
    "preview": "package net.minestom.vanilla.blocks.behaviours.oxidisable;\n\nimport net.minestom.server.entity.Player;\nimport net.minesto"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxidatedBlockBehaviour.java",
    "chars": 624,
    "preview": "package net.minestom.vanilla.blocks.behaviours.oxidisable;\n\nimport net.minestom.server.instance.block.Block;\nimport net."
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/OxygenSensitive.java",
    "chars": 122,
    "preview": "package net.minestom.vanilla.blocks.behaviours.oxidisable;\n\npublic interface OxygenSensitive {\n    int oxidisedLevel();\n"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/WaxableBlockBehaviour.java",
    "chars": 1571,
    "preview": "package net.minestom.vanilla.blocks.behaviours.oxidisable;\n\nimport net.minestom.server.entity.Player;\nimport net.minesto"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/oxidisable/WaxedBlockBehaviour.java",
    "chars": 1636,
    "preview": "package net.minestom.vanilla.blocks.behaviours.oxidisable;\n\nimport net.minestom.server.entity.Player;\nimport net.minesto"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/BlastingFurnaceBehaviour.java",
    "chars": 2251,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.s"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/CampfireBehaviour.java",
    "chars": 8659,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/CraftingTableBehaviour.java",
    "chars": 1671,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.minestom.server.entity.Player;\nimport net.minestom.se"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/FurnaceBehaviour.java",
    "chars": 2167,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.s"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/SmithingTableBehaviour.java",
    "chars": 1653,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.minestom.server.entity.Player;\nimport net.minestom.se"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/SmokerBehaviour.java",
    "chars": 2155,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.kyori.adventure.text.Component;\nimport net.minestom.s"
  },
  {
    "path": "blocks/src/main/java/net/minestom/vanilla/blocks/behaviours/recipe/StonecutterBehaviour.java",
    "chars": 1561,
    "preview": "package net.minestom.vanilla.blocks.behaviours.recipe;\n\nimport net.minestom.server.entity.Player;\nimport net.minestom.se"
  },
  {
    "path": "build.gradle.kts",
    "chars": 1532,
    "preview": "plugins {\n    java\n    `java-library`\n    `maven-publish`\n    id(\"com.github.harbby.gradle.serviceloader\") version (\"1.1"
  },
  {
    "path": "commands/build.gradle.kts",
    "chars": 93,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n    compileOnly(project(\":instance-meta\"))\n}"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/DifficultyCommand.java",
    "chars": 1857,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server.command.C"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/ForceloadCommand.java",
    "chars": 6511,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.minestom.server.command.CommandSender;\nimport net.minestom.server.com"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/GamemodeCommand.java",
    "chars": 5668,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.kyori.adventure.text.Component;\nimport net.kyori.adventure.text.forma"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/HelpCommand.java",
    "chars": 1043,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.minestom.server.command.CommandSender;\nimport net.minestom.server.com"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/MeCommand.java",
    "chars": 1877,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.kyori.adventure.text.Component;\nimport net.kyori.adventure.text.TextC"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/SaveAllCommand.java",
    "chars": 914,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server.command.C"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/StopCommand.java",
    "chars": 701,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server.command.C"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/VanillaCommands.java",
    "chars": 1119,
    "preview": "package net.minestom.vanilla.commands;\n\nimport net.minestom.server.command.CommandManager;\nimport net.minestom.server.co"
  },
  {
    "path": "commands/src/main/java/net/minestom/vanilla/commands/VanillaCommandsFeature.java",
    "chars": 930,
    "preview": "package net.minestom.vanilla.commands;\n\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.vanilla.VanillaReimplem"
  },
  {
    "path": "core/build.gradle.kts",
    "chars": 758,
    "preview": "dependencies {\n    // Minestom\n    api(\"net.minestom:minestom:${project.property(\"minestom_version\")}\")\n\n    // Raycasti"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/VanillaRegistry.java",
    "chars": 919,
    "preview": "package net.minestom.vanilla;\n\nimport net.minestom.server.coordinate.Pos;\nimport net.minestom.server.entity.Entity;\nimpo"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/VanillaReimplementation.java",
    "chars": 6043,
    "preview": "package net.minestom.vanilla;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.ServerProcess;\nimport net."
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/VanillaReimplementationImpl.java",
    "chars": 9901,
    "preview": "package net.minestom.vanilla;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.ServerProcess;\nimport net."
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/dimensions/VanillaDimensionTypes.java",
    "chars": 700,
    "preview": "package net.minestom.vanilla.dimensions;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.registry.Dynami"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/events/BlastingFurnaceTickEvent.java",
    "chars": 661,
    "preview": "package net.minestom.vanilla.events;\n\nimport net.minestom.server.coordinate.BlockVec;\nimport net.minestom.server.event.E"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/events/FurnaceTickEvent.java",
    "chars": 645,
    "preview": "package net.minestom.vanilla.events;\n\nimport net.minestom.server.coordinate.BlockVec;\nimport net.minestom.server.event.E"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/events/SmokerTickEvent.java",
    "chars": 643,
    "preview": "package net.minestom.vanilla.events;\n\nimport net.minestom.server.coordinate.BlockVec;\nimport net.minestom.server.event.E"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/ByteArray.java",
    "chars": 1733,
    "preview": "package net.minestom.vanilla.files;\n\nimport net.minestom.server.utils.MathUtils;\n\nimport java.io.ByteArrayInputStream;\ni"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/CacheFileSystem.java",
    "chars": 1373,
    "preview": "package net.minestom.vanilla.files;\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.function.Function;\nimp"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/DynamicFileSystem.java",
    "chars": 2779,
    "preview": "package net.minestom.vanilla.files;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.Map;\nimport java.util.S"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/FileSystem.java",
    "chars": 1859,
    "preview": "package net.minestom.vanilla.files;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.File;\nimport java.util.Se"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/FileSystemImpl.java",
    "chars": 2178,
    "preview": "package net.minestom.vanilla.files;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.Arrays;\nimport java.uti"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/FileSystemMappers.java",
    "chars": 930,
    "preview": "package net.minestom.vanilla.files;\n\nimport com.google.gson.JsonElement;\n\nimport java.io.InputStream;\nimport java.util.f"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/FileSystemUtil.java",
    "chars": 2029,
    "preview": "package net.minestom.vanilla.files;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonElement;\nimport org.jetbrai"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/LazyFileSystem.java",
    "chars": 1471,
    "preview": "package net.minestom.vanilla.files;\n\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Map;\nimport java.util."
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/MappedFileSystem.java",
    "chars": 942,
    "preview": "package net.minestom.vanilla.files;\n\nimport java.util.Set;\nimport java.util.function.BiFunction;\n\nclass MappedFileSystem"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/files/PathFileSystem.java",
    "chars": 1840,
    "preview": "package net.minestom.vanilla.files;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\n"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/instance/SetupVanillaInstanceEvent.java",
    "chars": 488,
    "preview": "package net.minestom.vanilla.instance;\n\nimport net.minestom.server.event.trait.InstanceEvent;\nimport net.minestom.server"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/instance/VanillaExplosion.java",
    "chars": 12488,
    "preview": "package net.minestom.vanilla.instance;\n\nimport dev.emortal.rayfast.area.Intersection;\nimport dev.emortal.rayfast.area.ar"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/inventory/InventoryManipulation.java",
    "chars": 1932,
    "preview": "package net.minestom.vanilla.inventory;\n\nimport net.minestom.server.component.DataComponents;\nimport net.minestom.server"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/Color.java",
    "chars": 3064,
    "preview": "package net.minestom.vanilla.logging;\n\npublic enum Color {\n    //Color end string, color reset\n    RESET(\"\\033[0m\"),\n\n  "
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/Level.java",
    "chars": 104,
    "preview": "package net.minestom.vanilla.logging;\n\npublic enum Level {\n    TRACE, DEBUG, SETUP, INFO, WARN, ERROR\n}\n"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/Loading.java",
    "chars": 409,
    "preview": "package net.minestom.vanilla.logging;\n\npublic interface Loading {\n\n    static void start(String name) {\n        LoadingI"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/LoadingBar.java",
    "chars": 432,
    "preview": "package net.minestom.vanilla.logging;\n\ninterface LoadingBar {\n\n    static LoadingBar console(String initialMessage) {\n  "
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/LoadingImpl.java",
    "chars": 1681,
    "preview": "package net.minestom.vanilla.logging;\n\nimport org.jetbrains.annotations.NotNull;\nimport org.jetbrains.annotations.Nullab"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/Logger.java",
    "chars": 3186,
    "preview": "package net.minestom.vanilla.logging;\n\npublic interface Logger {\n    static Logger logger() {\n        return LoggerImpl."
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/LoggerImpl.java",
    "chars": 4863,
    "preview": "package net.minestom.vanilla.logging;\n\nimport java.io.OutputStream;\nimport java.io.PrintStream;\nimport java.util.Calenda"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/LoggingLoadingBar.java",
    "chars": 4821,
    "preview": "package net.minestom.vanilla.logging;\n\nimport java.util.function.Consumer;\n\nclass LoggingLoadingBar implements LoadingBa"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/SLF4JCompatibilityLayer.java",
    "chars": 2385,
    "preview": "package net.minestom.vanilla.logging;\n\nimport org.slf4j.Marker;\nimport org.slf4j.helpers.AbstractLogger;\n\nclass SLF4JCom"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/SLF4JServiceProvider.java",
    "chars": 930,
    "preview": "package net.minestom.vanilla.logging;\n\nimport org.slf4j.ILoggerFactory;\nimport org.slf4j.IMarkerFactory;\nimport org.slf4"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/logging/StatusUpdater.java",
    "chars": 402,
    "preview": "package net.minestom.vanilla.logging;\n\npublic interface StatusUpdater {\n    /**\n     * Updates the progress bar without "
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/EnderChestSystem.java",
    "chars": 818,
    "preview": "package net.minestom.vanilla.system;\n\nimport net.minestom.server.entity.Player;\nimport net.minestom.server.item.ItemStac"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/NetherPortal.java",
    "chars": 18384,
    "preview": "package net.minestom.vanilla.system;\n\nimport it.unimi.dsi.fastutil.objects.ObjectArrayList;\nimport net.kyori.adventure.k"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/RayFastManager.java",
    "chars": 1034,
    "preview": "package net.minestom.vanilla.system;\n\nimport dev.emortal.rayfast.area.area3d.Area3d;\nimport dev.emortal.rayfast.area.are"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/ServerProperties.java",
    "chars": 1700,
    "preview": "package net.minestom.vanilla.system;\n\nimport java.io.*;\nimport java.util.Objects;\nimport java.util.Properties;\n\n/**\n * H"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/nether/EntityEnterNetherPortalEvent.java",
    "chars": 1408,
    "preview": "package net.minestom.vanilla.system.nether;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server.ent"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/nether/NetherPortalTeleportEvent.java",
    "chars": 4006,
    "preview": "package net.minestom.vanilla.system.nether;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server.ent"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/system/nether/NetherPortalUpdateEvent.java",
    "chars": 1726,
    "preview": "package net.minestom.vanilla.system.nether;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server.ent"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/tag/Tags.java",
    "chars": 3750,
    "preview": "package net.minestom.vanilla.tag;\n\nimport net.kyori.adventure.key.Key;\nimport net.kyori.adventure.nbt.*;\nimport net.mine"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/utils/DependencySorting.java",
    "chars": 1346,
    "preview": "package net.minestom.vanilla.utils;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/utils/JavaUtils.java",
    "chars": 543,
    "preview": "package net.minestom.vanilla.utils;\n\nimport java.util.Collection;\nimport java.util.random.RandomGenerator;\n\npublic class"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/utils/MathUtils.java",
    "chars": 1644,
    "preview": "package net.minestom.vanilla.utils;\n\nimport net.minestom.server.coordinate.Point;\n\nimport java.util.HashSet;\nimport java"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/utils/MinestomUtils.java",
    "chars": 1411,
    "preview": "package net.minestom.vanilla.utils;\n\nimport net.minestom.server.MinecraftServer;\nimport net.minestom.server.component.Da"
  },
  {
    "path": "core/src/main/java/net/minestom/vanilla/utils/ZipUtils.java",
    "chars": 2415,
    "preview": "package net.minestom.vanilla.utils;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.*;\nimport "
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.tinylog.writers.Writer",
    "chars": 50,
    "preview": "net.minestom.vanilla.VanillaReimplementationWriter"
  },
  {
    "path": "core/src/test/java/net/minestom/vanilla/files/FileSystemTests.java",
    "chars": 1283,
    "preview": "package net.minestom.vanilla.files;\n\n\nimport org.junit.jupiter.api.Test;\n\nimport static org.junit.jupiter.api.Assertions"
  },
  {
    "path": "crafting/build.gradle.kts",
    "chars": 171,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n    compileOnly(project(\":datapack\"))\n    implementation(\"net.goldensta"
  },
  {
    "path": "crafting/src/main/java/net/minestom/vanilla/crafting/CraftingFeature.java",
    "chars": 5769,
    "preview": "package net.minestom.vanilla.crafting;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.ServerProcess;\nim"
  },
  {
    "path": "crafting/src/main/java/net/minestom/vanilla/crafting/CraftingRecipes.java",
    "chars": 10289,
    "preview": "package net.minestom.vanilla.crafting;\n\nimport net.goldenstack.window.InventoryView;\nimport net.goldenstack.window.Views"
  },
  {
    "path": "crafting/src/main/java/net/minestom/vanilla/crafting/Recipe.java",
    "chars": 15809,
    "preview": "package net.minestom.vanilla.crafting;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.codec.Codec;\nimpo"
  },
  {
    "path": "datapack/build.gradle.kts",
    "chars": 50,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n}"
  },
  {
    "path": "datapack/src/main/java/net/minestom/vanilla/datapack/Datapacks.java",
    "chars": 10624,
    "preview": "package net.minestom.vanilla.datapack;\n\nimport com.google.gson.JsonParser;\nimport net.kyori.adventure.key.Key;\nimport ne"
  },
  {
    "path": "datapack-loading/build.gradle.kts",
    "chars": 208,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n    compileOnly(project(\":mojang-data\"))\n    implementation(\"space.vect"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/Datapack.java",
    "chars": 8321,
    "preview": "package net.minestom.vanilla.datapack;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Key;\nimport"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/DatapackLoader.java",
    "chars": 18340,
    "preview": "package net.minestom.vanilla.datapack;\n\nimport com.squareup.moshi.*;\nimport it.unimi.dsi.fastutil.doubles.DoubleArrayLis"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/DatapackLoadingFeature.java",
    "chars": 1342,
    "preview": "package net.minestom.vanilla.datapack;\n\nimport io.github.pesto.MojangDataFeature;\nimport net.kyori.adventure.key.Key;\nim"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/DatapackUtils.java",
    "chars": 5254,
    "preview": "package net.minestom.vanilla.datapack;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.vanilla.datapack.tags.Ta"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/advancement/Advancement.java",
    "chars": 51493,
    "preview": "package net.minestom.vanilla.datapack.advancement;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/dimension/DimensionType.java",
    "chars": 1278,
    "preview": "package net.minestom.vanilla.datapack.dimension;\n\nimport net.minestom.vanilla.datapack.number.NumberProvider;\n\n// {\n//  "
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/json/JsonUtils.java",
    "chars": 7717,
    "preview": "package net.minestom.vanilla.datapack.json;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Key;\ni"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/json/ListLike.java",
    "chars": 2854,
    "preview": "package net.minestom.vanilla.datapack.json;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport java.util.Collection;\nimp"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/json/Optional.java",
    "chars": 133,
    "preview": "package net.minestom.vanilla.datapack.json;\n\nimport com.squareup.moshi.JsonQualifier;\n\n@JsonQualifier\npublic @interface "
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/LootTable.java",
    "chars": 14163,
    "preview": "package net.minestom.vanilla.datapack.loot;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Key;\ni"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/NBTPath.java",
    "chars": 1979,
    "preview": "package net.minestom.vanilla.datapack.loot;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.nbt.Binary"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/NBTPathImpl.java",
    "chars": 18857,
    "preview": "package net.minestom.vanilla.datapack.loot;\n\nimport it.unimi.dsi.fastutil.ints.IntSet;\nimport net.kyori.adventure.nbt.*;"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/ContextGroups.java",
    "chars": 2756,
    "preview": "package net.minestom.vanilla.datapack.loot.context;\n\nimport net.kyori.adventure.nbt.CompoundBinaryTag;\nimport net.kyori."
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/LootContext.java",
    "chars": 9079,
    "preview": "package net.minestom.vanilla.datapack.loot.context;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.server.co"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/MappedTraitImpl.java",
    "chars": 561,
    "preview": "package net.minestom.vanilla.datapack.loot.context;\n\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.functi"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/TraitImpl.java",
    "chars": 442,
    "preview": "package net.minestom.vanilla.datapack.loot.context;\n\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.functi"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/Traits.java",
    "chars": 1898,
    "preview": "package net.minestom.vanilla.datapack.loot.context;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.se"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/context/Util.java",
    "chars": 1651,
    "preview": "package net.minestom.vanilla.datapack.loot.context;\n\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.HashMa"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/InBuiltLootFunctions.java",
    "chars": 35111,
    "preview": "package net.minestom.vanilla.datapack.loot.function;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.k"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/InBuiltPredicates.java",
    "chars": 18943,
    "preview": "package net.minestom.vanilla.datapack.loot.function;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.k"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/LootFunction.java",
    "chars": 3217,
    "preview": "package net.minestom.vanilla.datapack.loot.function;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.k"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/loot/function/Predicate.java",
    "chars": 1851,
    "preview": "package net.minestom.vanilla.datapack.loot.function;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.vanilla."
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/nbt/NBTUtils.java",
    "chars": 4340,
    "preview": "package net.minestom.vanilla.datapack.nbt;\n\nimport net.kyori.adventure.nbt.BinaryTag;\nimport net.kyori.adventure.nbt.Com"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/number/DoubleNumberProviders.java",
    "chars": 1223,
    "preview": "package net.minestom.vanilla.datapack.number;\n\nimport java.util.random.RandomGenerator;\n\ninterface DoubleNumberProviders"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/number/IntNumberProviders.java",
    "chars": 1190,
    "preview": "package net.minestom.vanilla.datapack.number;\n\nimport java.util.random.RandomGenerator;\n\ninterface IntNumberProviders {\n"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/number/NumberProvider.java",
    "chars": 3069,
    "preview": "package net.minestom.vanilla.datapack.number;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.vanilla.datapac"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/recipe/Recipe.java",
    "chars": 11211,
    "preview": "package net.minestom.vanilla.datapack.recipe;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonReader;\nimp"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/tags/ConditionsFor.java",
    "chars": 299,
    "preview": "package net.minestom.vanilla.datapack.tags;\n\npublic class ConditionsFor {\n    public record Location() {\n    }\n\n    publ"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/tags/Tag.java",
    "chars": 390,
    "preview": "package net.minestom.vanilla.datapack.tags;\n\nimport net.kyori.adventure.key.Key;\nimport org.jetbrains.annotations.NotNul"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/trims/TrimMaterial.java",
    "chars": 604,
    "preview": "package net.minestom.vanilla.datapack.trims;\n\nimport net.kyori.adventure.key.Key;\nimport net.kyori.adventure.text.Compon"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/trims/TrimPattern.java",
    "chars": 620,
    "preview": "package net.minestom.vanilla.datapack.trims;\n\nimport net.kyori.adventure.key.Key;\nimport net.kyori.adventure.text.Compon"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/Biome.java",
    "chars": 17121,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Ke"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/BlockState.java",
    "chars": 1268,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.server.instan"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/Carver.java",
    "chars": 6247,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Ke"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/DensityFunction.java",
    "chars": 3644,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.vanilla.datap"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/DensityFunctions.java",
    "chars": 24431,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.Json;\nimport com.squareup.moshi.JsonReader;\ni"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/FloatProvider.java",
    "chars": 2639,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Ke"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/HeightProvider.java",
    "chars": 3738,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\nimport net.kyori.adventure.key.Ke"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/LazyLoadedDensityFunction.java",
    "chars": 1175,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport net.minestom.vanilla.datapack.DatapackLoader;\nimport net.minesto"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/NoiseSettings.java",
    "chars": 26517,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonElement;\nimport"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/Structure.java",
    "chars": 7018,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport net.kyori.adventure.nbt.*;\nimport net.minestom.server.coordinate"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/VerticalAnchor.java",
    "chars": 1429,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.squareup.moshi.JsonReader;\n\nimport java.io.IOException;\n\nsea"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/WorldgenContext.java",
    "chars": 400,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport net.minestom.server.world.DimensionType;\n\npublic interface World"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/WorldgenRegistries.java",
    "chars": 434,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport it.unimi.dsi.fastutil.doubles.DoubleList;\nimport net.minestom.va"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/biome/BiomeSource.java",
    "chars": 2189,
    "preview": "package net.minestom.vanilla.datapack.worldgen.biome;\n\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonOb"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/biome/BiomeSources.java",
    "chars": 4999,
    "preview": "package net.minestom.vanilla.datapack.worldgen.biome;\n\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonElem"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/biome/Climate.java",
    "chars": 23529,
    "preview": "package net.minestom.vanilla.datapack.worldgen.biome;\n\n\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonO"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/math/CubicSpline.java",
    "chars": 7390,
    "preview": "package net.minestom.vanilla.datapack.worldgen.math;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.vanilla."
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/math/NumberFunction.java",
    "chars": 118,
    "preview": "package net.minestom.vanilla.datapack.worldgen.math;\n\npublic interface NumberFunction<C> {\n    double compute(C c);\n}\n"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/math/SplineInterpolator.java",
    "chars": 4743,
    "preview": "package net.minestom.vanilla.datapack.worldgen.math;\n\nimport it.unimi.dsi.fastutil.doubles.DoubleList;\n\n/**\n * Performs "
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/BlendedNoise.java",
    "chars": 3577,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport net.minestom.vanilla.datapack.worldgen.random.WorldgenRand"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/ImprovedNoise.java",
    "chars": 3056,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport net.minestom.vanilla.datapack.worldgen.random.WorldgenRand"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/LazyLoadedNoise.java",
    "chars": 993,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport net.minestom.vanilla.datapack.DatapackLoader;\nimport net.m"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/Noise.java",
    "chars": 1530,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport com.squareup.moshi.JsonReader;\nimport net.minestom.vanilla"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/NormalNoise.java",
    "chars": 1809,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport it.unimi.dsi.fastutil.doubles.DoubleList;\nimport net.mines"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/PerlinNoise.java",
    "chars": 3727,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport it.unimi.dsi.fastutil.doubles.DoubleList;\nimport net.mines"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/noise/SimplexNoise.java",
    "chars": 6104,
    "preview": "package net.minestom.vanilla.datapack.worldgen.noise;\n\nimport net.minestom.vanilla.datapack.worldgen.random.WorldgenRand"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/LegacyRandom.java",
    "chars": 2120,
    "preview": "package net.minestom.vanilla.datapack.worldgen.random;\n\npublic class LegacyRandom implements WorldgenRandom {\n\n    priva"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/MarsagliaPolarGaussian.java",
    "chars": 1121,
    "preview": "package net.minestom.vanilla.datapack.worldgen.random;\n\nimport net.minestom.vanilla.datapack.worldgen.util.Util;\n\nclass "
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/WorldgenRandom.java",
    "chars": 989,
    "preview": "package net.minestom.vanilla.datapack.worldgen.random;\n\nimport net.minestom.vanilla.datapack.worldgen.util.Util;\n\nimport"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/XoroshiroPositionalRandom.java",
    "chars": 1196,
    "preview": "package net.minestom.vanilla.datapack.worldgen.random;\n\nimport net.minestom.vanilla.datapack.worldgen.util.Util;\n\nimport"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/random/XoroshiroRandom.java",
    "chars": 2771,
    "preview": "package net.minestom.vanilla.datapack.worldgen.random;\n\nimport net.minestom.vanilla.datapack.worldgen.util.Util;\n\npublic"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorage.java",
    "chars": 1020,
    "preview": "package net.minestom.vanilla.datapack.worldgen.storage;\n\nimport net.minestom.vanilla.datapack.worldgen.DensityFunction;\n"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorageCache.java",
    "chars": 973,
    "preview": "package net.minestom.vanilla.datapack.worldgen.storage;\n\nimport it.unimi.dsi.fastutil.longs.Long2DoubleMap;\nimport it.un"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorageCache2d.java",
    "chars": 748,
    "preview": "package net.minestom.vanilla.datapack.worldgen.storage;\n\nimport it.unimi.dsi.fastutil.longs.Long2DoubleMap;\nimport it.un"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/storage/DoubleStorageThreadLocalImpl.java",
    "chars": 480,
    "preview": "package net.minestom.vanilla.datapack.worldgen.storage;\n\nimport java.util.function.Supplier;\n\nclass DoubleStorageThreadL"
  },
  {
    "path": "datapack-loading/src/main/java/net/minestom/vanilla/datapack/worldgen/util/Util.java",
    "chars": 7835,
    "preview": "package net.minestom.vanilla.datapack.worldgen.util;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimp"
  },
  {
    "path": "datapack-tests/build.gradle.kts",
    "chars": 603,
    "preview": "plugins {\n    id(\"org.spongepowered.gradle.vanilla\") version \"0.2.1-SNAPSHOT\"\n}\n\ndependencies {\n    compileOnly(project("
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/loot/LootTableTestData.java",
    "chars": 109857,
    "preview": "package net.minestom.vanilla.datapack.loot;\n\nimport net.kyori.adventure.nbt.CompoundBinaryTag;\nimport net.minestom.serve"
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/loot/LootTableTests.java",
    "chars": 8694,
    "preview": "package net.minestom.vanilla.datapack.loot;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonElement;\nimport com"
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/DF.java",
    "chars": 1820,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonElement;\nimport"
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/DFVisualizer.java",
    "chars": 4515,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport com.google.common.util.concurrent.AtomicDouble;\n\nimport javax.sw"
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/DensityFunctionTests.java",
    "chars": 7309,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport net.minecraft.SharedConstants;\nimport net.minecraft.server.Boots"
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/NoiseTests.java",
    "chars": 2760,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport net.minecraft.world.level.levelgen.LegacyRandomSource;\nimport ne"
  },
  {
    "path": "datapack-tests/src/test/java/net/minestom/vanilla/datapack/worldgen/RandomTests.java",
    "chars": 2109,
    "preview": "package net.minestom.vanilla.datapack.worldgen;\n\nimport net.minecraft.world.level.levelgen.LegacyRandomSource;\nimport ne"
  },
  {
    "path": "entities/build.gradle.kts",
    "chars": 91,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n    compileOnly(project(\":entity-meta\"))\n}"
  },
  {
    "path": "entities/src/main/java/net/minestom/vanilla/entities/FallingBlockEntity.java",
    "chars": 2152,
    "preview": "package net.minestom.vanilla.entities;\n\nimport net.minestom.server.coordinate.Pos;\nimport net.minestom.server.entity.Ent"
  },
  {
    "path": "entities/src/main/java/net/minestom/vanilla/entities/MinestomEntitiesFeature.java",
    "chars": 632,
    "preview": "package net.minestom.vanilla.entities;\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.server.entity.EntityType"
  },
  {
    "path": "entities/src/main/java/net/minestom/vanilla/entities/PrimedTNTEntity.java",
    "chars": 1756,
    "preview": "package net.minestom.vanilla.entities;\n\nimport net.minestom.server.entity.Entity;\nimport net.minestom.server.entity.Enti"
  },
  {
    "path": "entity-meta/build.gradle.kts",
    "chars": 50,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n}"
  },
  {
    "path": "entity-meta/src/main/java/net/minestom/vanilla/entitymeta/EntityTags.java",
    "chars": 523,
    "preview": "package net.minestom.vanilla.entitymeta;\n\nimport net.minestom.server.instance.block.Block;\nimport net.minestom.server.ta"
  },
  {
    "path": "fluid-simulation/build.gradle.kts",
    "chars": 99,
    "preview": "dependencies {\n    compileOnly(project(\":core\"))\n    compileOnly(project(\":block-update-system\"))\n}"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/EmptyFluid.java",
    "chars": 1003,
    "preview": "package io.github.togar2.fluids;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server.instance.Insta"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/FlowableFluid.java",
    "chars": 14610,
    "preview": "package io.github.togar2.fluids;\n\nimport it.unimi.dsi.fastutil.shorts.Short2BooleanMap;\nimport it.unimi.dsi.fastutil.sho"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/Fluid.java",
    "chars": 1918,
    "preview": "package io.github.togar2.fluids;\n\nimport net.minestom.server.coordinate.Point;\nimport net.minestom.server.instance.Insta"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/FluidPlacementRule.java",
    "chars": 755,
    "preview": "package io.github.togar2.fluids;\n\nimport net.minestom.server.instance.Instance;\nimport net.minestom.server.instance.bloc"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/FluidSimulationFeature.java",
    "chars": 749,
    "preview": "package io.github.togar2.fluids;\n\n\nimport net.kyori.adventure.key.Key;\nimport net.minestom.vanilla.BlockUpdateFeature;\ni"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/MinestomFluids.java",
    "chars": 2438,
    "preview": "package io.github.togar2.fluids;\n\nimport net.minestom.server.ServerProcess;\nimport net.minestom.server.coordinate.Point;"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/WaterBlockBreakEvent.java",
    "chars": 1290,
    "preview": "package io.github.togar2.fluids;\n\nimport net.minestom.server.coordinate.BlockVec;\nimport net.minestom.server.event.trait"
  },
  {
    "path": "fluid-simulation/src/main/java/io/github/togar2/fluids/WaterFluid.java",
    "chars": 1320,
    "preview": "package io.github.togar2.fluids;\n\nimport net.minestom.server.coordinate.BlockVec;\nimport net.minestom.server.coordinate."
  }
]

// ... and 63 more files (download for full content)

About this extraction

This page contains the full source code of the Minestom/VanillaReimplementation GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 263 files (1.1 MB), approximately 272.7k tokens, and a symbol index with 2384 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!