aboutsummaryrefslogtreecommitdiffhomepage
path: root/paper-api-generator
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2023-11-22 20:56:28 -0800
committerGitHub <[email protected]>2023-11-22 20:56:28 -0800
commit96d5e6ca481591842f44d05ab2451f943be6a7c7 (patch)
treead35d855fa33f6feb8e365ce12aa312bd225ff3f /paper-api-generator
parente1cd9e59e53aabd50e501cb01feee277a8f69902 (diff)
downloadPaper-96d5e6ca481591842f44d05ab2451f943be6a7c7.tar.gz
Paper-96d5e6ca481591842f44d05ab2451f943be6a7c7.zip
Code Generation for TypedKeys (#9233)
Currently includes generated key holder classes for types used in the Registry Modification API
Diffstat (limited to 'paper-api-generator')
-rw-r--r--paper-api-generator/build.gradle.kts28
-rw-r--r--paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java490
-rw-r--r--paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java462
-rw-r--r--paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java147
-rw-r--r--paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java112
-rw-r--r--paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java154
-rw-r--r--paper-api-generator/src/main/java/io/papermc/generator/Main.java85
-rw-r--r--paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java24
-rw-r--r--paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java205
-rw-r--r--paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java11
-rw-r--r--paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java28
-rw-r--r--paper-api-generator/wideners.at6
12 files changed, 1752 insertions, 0 deletions
diff --git a/paper-api-generator/build.gradle.kts b/paper-api-generator/build.gradle.kts
new file mode 100644
index 0000000000..50cc3c1e59
--- /dev/null
+++ b/paper-api-generator/build.gradle.kts
@@ -0,0 +1,28 @@
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform
+
+plugins {
+ java
+ id("org.spongepowered.gradle.vanilla") version "0.2.1-SNAPSHOT"
+}
+
+minecraft {
+ version(property("mcVersion").toString())
+ platform(MinecraftPlatform.SERVER)
+
+ runs {
+ server("generate") {
+ mainClass("io.papermc.generator.Main")
+ accessWideners(projectDir.toPath().resolve("wideners.at"))
+ args(projectDir.toPath().resolve("generated").toString())
+ }
+ }
+}
+
+dependencies {
+ implementation("com.squareup:javapoet:1.13.0")
+ implementation(project(":paper-api"))
+}
+
+group = "io.papermc.paper"
+version = "1.0-SNAPSHOT"
+
diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java
new file mode 100644
index 0000000000..84e6385588
--- /dev/null
+++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java
@@ -0,0 +1,490 @@
+package io.papermc.paper.registry.keys;
+
+import static net.kyori.adventure.key.Key.key;
+
+import io.papermc.paper.generated.GeneratedFrom;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import net.kyori.adventure.key.Key;
+import org.bukkit.block.Biome;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Vanilla keys for {@link RegistryKey#BIOME}.
+ *
+ * @apiNote The fields provided here are a direct representation of
+ * what is available from the vanilla game source. They may be
+ * changed (including removals) on any Minecraft version
+ * bump, so cross-version compatibility is not provided on the
+ * same level as it is on most of the other API.
+ */
+@SuppressWarnings({
+ "unused",
+ "SpellCheckingInspection"
+})
+@GeneratedFrom("1.20.2")
+public final class BiomeKeys {
+ /**
+ * {@code minecraft:badlands}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> BADLANDS = create(key("badlands"));
+
+ /**
+ * {@code minecraft:bamboo_jungle}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> BAMBOO_JUNGLE = create(key("bamboo_jungle"));
+
+ /**
+ * {@code minecraft:basalt_deltas}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> BASALT_DELTAS = create(key("basalt_deltas"));
+
+ /**
+ * {@code minecraft:beach}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> BEACH = create(key("beach"));
+
+ /**
+ * {@code minecraft:birch_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> BIRCH_FOREST = create(key("birch_forest"));
+
+ /**
+ * {@code minecraft:cherry_grove}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> CHERRY_GROVE = create(key("cherry_grove"));
+
+ /**
+ * {@code minecraft:cold_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> COLD_OCEAN = create(key("cold_ocean"));
+
+ /**
+ * {@code minecraft:crimson_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> CRIMSON_FOREST = create(key("crimson_forest"));
+
+ /**
+ * {@code minecraft:dark_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DARK_FOREST = create(key("dark_forest"));
+
+ /**
+ * {@code minecraft:deep_cold_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DEEP_COLD_OCEAN = create(key("deep_cold_ocean"));
+
+ /**
+ * {@code minecraft:deep_dark}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DEEP_DARK = create(key("deep_dark"));
+
+ /**
+ * {@code minecraft:deep_frozen_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DEEP_FROZEN_OCEAN = create(key("deep_frozen_ocean"));
+
+ /**
+ * {@code minecraft:deep_lukewarm_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DEEP_LUKEWARM_OCEAN = create(key("deep_lukewarm_ocean"));
+
+ /**
+ * {@code minecraft:deep_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DEEP_OCEAN = create(key("deep_ocean"));
+
+ /**
+ * {@code minecraft:desert}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DESERT = create(key("desert"));
+
+ /**
+ * {@code minecraft:dripstone_caves}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> DRIPSTONE_CAVES = create(key("dripstone_caves"));
+
+ /**
+ * {@code minecraft:end_barrens}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> END_BARRENS = create(key("end_barrens"));
+
+ /**
+ * {@code minecraft:end_highlands}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> END_HIGHLANDS = create(key("end_highlands"));
+
+ /**
+ * {@code minecraft:end_midlands}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> END_MIDLANDS = create(key("end_midlands"));
+
+ /**
+ * {@code minecraft:eroded_badlands}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> ERODED_BADLANDS = create(key("eroded_badlands"));
+
+ /**
+ * {@code minecraft:flower_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> FLOWER_FOREST = create(key("flower_forest"));
+
+ /**
+ * {@code minecraft:forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> FOREST = create(key("forest"));
+
+ /**
+ * {@code minecraft:frozen_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> FROZEN_OCEAN = create(key("frozen_ocean"));
+
+ /**
+ * {@code minecraft:frozen_peaks}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> FROZEN_PEAKS = create(key("frozen_peaks"));
+
+ /**
+ * {@code minecraft:frozen_river}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> FROZEN_RIVER = create(key("frozen_river"));
+
+ /**
+ * {@code minecraft:grove}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> GROVE = create(key("grove"));
+
+ /**
+ * {@code minecraft:ice_spikes}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> ICE_SPIKES = create(key("ice_spikes"));
+
+ /**
+ * {@code minecraft:jagged_peaks}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> JAGGED_PEAKS = create(key("jagged_peaks"));
+
+ /**
+ * {@code minecraft:jungle}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> JUNGLE = create(key("jungle"));
+
+ /**
+ * {@code minecraft:lukewarm_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> LUKEWARM_OCEAN = create(key("lukewarm_ocean"));
+
+ /**
+ * {@code minecraft:lush_caves}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> LUSH_CAVES = create(key("lush_caves"));
+
+ /**
+ * {@code minecraft:mangrove_swamp}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> MANGROVE_SWAMP = create(key("mangrove_swamp"));
+
+ /**
+ * {@code minecraft:meadow}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> MEADOW = create(key("meadow"));
+
+ /**
+ * {@code minecraft:mushroom_fields}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> MUSHROOM_FIELDS = create(key("mushroom_fields"));
+
+ /**
+ * {@code minecraft:nether_wastes}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> NETHER_WASTES = create(key("nether_wastes"));
+
+ /**
+ * {@code minecraft:ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> OCEAN = create(key("ocean"));
+
+ /**
+ * {@code minecraft:old_growth_birch_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> OLD_GROWTH_BIRCH_FOREST = create(key("old_growth_birch_forest"));
+
+ /**
+ * {@code minecraft:old_growth_pine_taiga}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> OLD_GROWTH_PINE_TAIGA = create(key("old_growth_pine_taiga"));
+
+ /**
+ * {@code minecraft:old_growth_spruce_taiga}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> OLD_GROWTH_SPRUCE_TAIGA = create(key("old_growth_spruce_taiga"));
+
+ /**
+ * {@code minecraft:plains}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> PLAINS = create(key("plains"));
+
+ /**
+ * {@code minecraft:river}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> RIVER = create(key("river"));
+
+ /**
+ * {@code minecraft:savanna}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SAVANNA = create(key("savanna"));
+
+ /**
+ * {@code minecraft:savanna_plateau}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SAVANNA_PLATEAU = create(key("savanna_plateau"));
+
+ /**
+ * {@code minecraft:small_end_islands}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SMALL_END_ISLANDS = create(key("small_end_islands"));
+
+ /**
+ * {@code minecraft:snowy_beach}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SNOWY_BEACH = create(key("snowy_beach"));
+
+ /**
+ * {@code minecraft:snowy_plains}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SNOWY_PLAINS = create(key("snowy_plains"));
+
+ /**
+ * {@code minecraft:snowy_slopes}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SNOWY_SLOPES = create(key("snowy_slopes"));
+
+ /**
+ * {@code minecraft:snowy_taiga}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SNOWY_TAIGA = create(key("snowy_taiga"));
+
+ /**
+ * {@code minecraft:soul_sand_valley}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SOUL_SAND_VALLEY = create(key("soul_sand_valley"));
+
+ /**
+ * {@code minecraft:sparse_jungle}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SPARSE_JUNGLE = create(key("sparse_jungle"));
+
+ /**
+ * {@code minecraft:stony_peaks}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> STONY_PEAKS = create(key("stony_peaks"));
+
+ /**
+ * {@code minecraft:stony_shore}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> STONY_SHORE = create(key("stony_shore"));
+
+ /**
+ * {@code minecraft:sunflower_plains}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SUNFLOWER_PLAINS = create(key("sunflower_plains"));
+
+ /**
+ * {@code minecraft:swamp}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> SWAMP = create(key("swamp"));
+
+ /**
+ * {@code minecraft:taiga}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> TAIGA = create(key("taiga"));
+
+ /**
+ * {@code minecraft:the_end}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> THE_END = create(key("the_end"));
+
+ /**
+ * {@code minecraft:the_void}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> THE_VOID = create(key("the_void"));
+
+ /**
+ * {@code minecraft:warm_ocean}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WARM_OCEAN = create(key("warm_ocean"));
+
+ /**
+ * {@code minecraft:warped_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WARPED_FOREST = create(key("warped_forest"));
+
+ /**
+ * {@code minecraft:windswept_forest}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WINDSWEPT_FOREST = create(key("windswept_forest"));
+
+ /**
+ * {@code minecraft:windswept_gravelly_hills}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WINDSWEPT_GRAVELLY_HILLS = create(key("windswept_gravelly_hills"));
+
+ /**
+ * {@code minecraft:windswept_hills}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WINDSWEPT_HILLS = create(key("windswept_hills"));
+
+ /**
+ * {@code minecraft:windswept_savanna}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WINDSWEPT_SAVANNA = create(key("windswept_savanna"));
+
+ /**
+ * {@code minecraft:wooded_badlands}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<Biome> WOODED_BADLANDS = create(key("wooded_badlands"));
+
+ private BiomeKeys() {
+ }
+
+ /**
+ * Creates a key for {@link Biome} in a registry.
+ *
+ * @param key the value's key in the registry
+ * @return a new typed key
+ */
+ @ApiStatus.Experimental
+ public static @NotNull TypedKey<Biome> create(final @NotNull Key key) {
+ return TypedKey.create(RegistryKey.BIOME, key);
+ }
+}
diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java
new file mode 100644
index 0000000000..978ed4aed5
--- /dev/null
+++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java
@@ -0,0 +1,462 @@
+package io.papermc.paper.registry.keys;
+
+import static net.kyori.adventure.key.Key.key;
+
+import io.papermc.paper.generated.GeneratedFrom;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import net.kyori.adventure.key.Key;
+import org.bukkit.GameEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Vanilla keys for {@link RegistryKey#GAME_EVENT}.
+ *
+ * @apiNote The fields provided here are a direct representation of
+ * what is available from the vanilla game source. They may be
+ * changed (including removals) on any Minecraft version
+ * bump, so cross-version compatibility is not provided on the
+ * same level as it is on most of the other API.
+ */
+@SuppressWarnings({
+ "unused",
+ "SpellCheckingInspection"
+})
+@GeneratedFrom("1.20.2")
+public final class GameEventKeys {
+ /**
+ * {@code minecraft:block_activate}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_ACTIVATE = create(key("block_activate"));
+
+ /**
+ * {@code minecraft:block_attach}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_ATTACH = create(key("block_attach"));
+
+ /**
+ * {@code minecraft:block_change}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_CHANGE = create(key("block_change"));
+
+ /**
+ * {@code minecraft:block_close}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_CLOSE = create(key("block_close"));
+
+ /**
+ * {@code minecraft:block_deactivate}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_DEACTIVATE = create(key("block_deactivate"));
+
+ /**
+ * {@code minecraft:block_destroy}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_DESTROY = create(key("block_destroy"));
+
+ /**
+ * {@code minecraft:block_detach}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_DETACH = create(key("block_detach"));
+
+ /**
+ * {@code minecraft:block_open}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_OPEN = create(key("block_open"));
+
+ /**
+ * {@code minecraft:block_place}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> BLOCK_PLACE = create(key("block_place"));
+
+ /**
+ * {@code minecraft:container_close}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> CONTAINER_CLOSE = create(key("container_close"));
+
+ /**
+ * {@code minecraft:container_open}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> CONTAINER_OPEN = create(key("container_open"));
+
+ /**
+ * {@code minecraft:drink}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> DRINK = create(key("drink"));
+
+ /**
+ * {@code minecraft:eat}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> EAT = create(key("eat"));
+
+ /**
+ * {@code minecraft:elytra_glide}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ELYTRA_GLIDE = create(key("elytra_glide"));
+
+ /**
+ * {@code minecraft:entity_damage}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_DAMAGE = create(key("entity_damage"));
+
+ /**
+ * {@code minecraft:entity_die}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_DIE = create(key("entity_die"));
+
+ /**
+ * {@code minecraft:entity_dismount}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_DISMOUNT = create(key("entity_dismount"));
+
+ /**
+ * {@code minecraft:entity_interact}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_INTERACT = create(key("entity_interact"));
+
+ /**
+ * {@code minecraft:entity_mount}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_MOUNT = create(key("entity_mount"));
+
+ /**
+ * {@code minecraft:entity_place}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_PLACE = create(key("entity_place"));
+
+ /**
+ * {@code minecraft:entity_action}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ENTITY_ACTION = create(key("entity_action"));
+
+ /**
+ * {@code minecraft:equip}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> EQUIP = create(key("equip"));
+
+ /**
+ * {@code minecraft:explode}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> EXPLODE = create(key("explode"));
+
+ /**
+ * {@code minecraft:flap}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> FLAP = create(key("flap"));
+
+ /**
+ * {@code minecraft:fluid_pickup}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> FLUID_PICKUP = create(key("fluid_pickup"));
+
+ /**
+ * {@code minecraft:fluid_place}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> FLUID_PLACE = create(key("fluid_place"));
+
+ /**
+ * {@code minecraft:hit_ground}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> HIT_GROUND = create(key("hit_ground"));
+
+ /**
+ * {@code minecraft:instrument_play}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> INSTRUMENT_PLAY = create(key("instrument_play"));
+
+ /**
+ * {@code minecraft:item_interact_finish}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ITEM_INTERACT_FINISH = create(key("item_interact_finish"));
+
+ /**
+ * {@code minecraft:item_interact_start}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> ITEM_INTERACT_START = create(key("item_interact_start"));
+
+ /**
+ * {@code minecraft:jukebox_play}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> JUKEBOX_PLAY = create(key("jukebox_play"));
+
+ /**
+ * {@code minecraft:jukebox_stop_play}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> JUKEBOX_STOP_PLAY = create(key("jukebox_stop_play"));
+
+ /**
+ * {@code minecraft:lightning_strike}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> LIGHTNING_STRIKE = create(key("lightning_strike"));
+
+ /**
+ * {@code minecraft:note_block_play}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> NOTE_BLOCK_PLAY = create(key("note_block_play"));
+
+ /**
+ * {@code minecraft:prime_fuse}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> PRIME_FUSE = create(key("prime_fuse"));
+
+ /**
+ * {@code minecraft:projectile_land}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> PROJECTILE_LAND = create(key("projectile_land"));
+
+ /**
+ * {@code minecraft:projectile_shoot}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> PROJECTILE_SHOOT = create(key("projectile_shoot"));
+
+ /**
+ * {@code minecraft:sculk_sensor_tendrils_clicking}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> SCULK_SENSOR_TENDRILS_CLICKING = create(key("sculk_sensor_tendrils_clicking"));
+
+ /**
+ * {@code minecraft:shear}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> SHEAR = create(key("shear"));
+
+ /**
+ * {@code minecraft:shriek}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> SHRIEK = create(key("shriek"));
+
+ /**
+ * {@code minecraft:splash}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> SPLASH = create(key("splash"));
+
+ /**
+ * {@code minecraft:step}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> STEP = create(key("step"));
+
+ /**
+ * {@code minecraft:swim}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> SWIM = create(key("swim"));
+
+ /**
+ * {@code minecraft:teleport}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> TELEPORT = create(key("teleport"));
+
+ /**
+ * {@code minecraft:unequip}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> UNEQUIP = create(key("unequip"));
+
+ /**
+ * {@code minecraft:resonate_1}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_1 = create(key("resonate_1"));
+
+ /**
+ * {@code minecraft:resonate_2}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_2 = create(key("resonate_2"));
+
+ /**
+ * {@code minecraft:resonate_3}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_3 = create(key("resonate_3"));
+
+ /**
+ * {@code minecraft:resonate_4}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_4 = create(key("resonate_4"));
+
+ /**
+ * {@code minecraft:resonate_5}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_5 = create(key("resonate_5"));
+
+ /**
+ * {@code minecraft:resonate_6}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_6 = create(key("resonate_6"));
+
+ /**
+ * {@code minecraft:resonate_7}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_7 = create(key("resonate_7"));
+
+ /**
+ * {@code minecraft:resonate_8}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_8 = create(key("resonate_8"));
+
+ /**
+ * {@code minecraft:resonate_9}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_9 = create(key("resonate_9"));
+
+ /**
+ * {@code minecraft:resonate_10}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_10 = create(key("resonate_10"));
+
+ /**
+ * {@code minecraft:resonate_11}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_11 = create(key("resonate_11"));
+
+ /**
+ * {@code minecraft:resonate_12}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_12 = create(key("resonate_12"));
+
+ /**
+ * {@code minecraft:resonate_13}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_13 = create(key("resonate_13"));
+
+ /**
+ * {@code minecraft:resonate_14}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_14 = create(key("resonate_14"));
+
+ /**
+ * {@code minecraft:resonate_15}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<GameEvent> RESONATE_15 = create(key("resonate_15"));
+
+ private GameEventKeys() {
+ }
+
+ /**
+ * Creates a key for {@link GameEvent} in a registry.
+ *
+ * @param key the value's key in the registry
+ * @return a new typed key
+ */
+ @ApiStatus.Experimental
+ public static @NotNull TypedKey<GameEvent> create(final @NotNull Key key) {
+ return TypedKey.create(RegistryKey.GAME_EVENT, key);
+ }
+}
diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java
new file mode 100644
index 0000000000..03fc2b494f
--- /dev/null
+++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java
@@ -0,0 +1,147 @@
+package io.papermc.paper.registry.keys;
+
+import static net.kyori.adventure.key.Key.key;
+
+import io.papermc.paper.generated.GeneratedFrom;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import net.kyori.adventure.key.Key;
+import org.bukkit.generator.structure.StructureType;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Vanilla keys for {@link RegistryKey#STRUCTURE_TYPE}.
+ *
+ * @apiNote The fields provided here are a direct representation of
+ * what is available from the vanilla game source. They may be
+ * changed (including removals) on any Minecraft version
+ * bump, so cross-version compatibility is not provided on the
+ * same level as it is on most of the other API.
+ */
+@SuppressWarnings({
+ "unused",
+ "SpellCheckingInspection"
+})
+@GeneratedFrom("1.20.2")
+public final class StructureTypeKeys {
+ /**
+ * {@code minecraft:buried_treasure}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> BURIED_TREASURE = create(key("buried_treasure"));
+
+ /**
+ * {@code minecraft:desert_pyramid}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> DESERT_PYRAMID = create(key("desert_pyramid"));
+
+ /**
+ * {@code minecraft:end_city}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> END_CITY = create(key("end_city"));
+
+ /**
+ * {@code minecraft:fortress}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> FORTRESS = create(key("fortress"));
+
+ /**
+ * {@code minecraft:igloo}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> IGLOO = create(key("igloo"));
+
+ /**
+ * {@code minecraft:jigsaw}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> JIGSAW = create(key("jigsaw"));
+
+ /**
+ * {@code minecraft:jungle_temple}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> JUNGLE_TEMPLE = create(key("jungle_temple"));
+
+ /**
+ * {@code minecraft:mineshaft}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> MINESHAFT = create(key("mineshaft"));
+
+ /**
+ * {@code minecraft:nether_fossil}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> NETHER_FOSSIL = create(key("nether_fossil"));
+
+ /**
+ * {@code minecraft:ocean_monument}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> OCEAN_MONUMENT = create(key("ocean_monument"));
+
+ /**
+ * {@code minecraft:ocean_ruin}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> OCEAN_RUIN = create(key("ocean_ruin"));
+
+ /**
+ * {@code minecraft:ruined_portal}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> RUINED_PORTAL = create(key("ruined_portal"));
+
+ /**
+ * {@code minecraft:shipwreck}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> SHIPWRECK = create(key("shipwreck"));
+
+ /**
+ * {@code minecraft:stronghold}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> STRONGHOLD = create(key("stronghold"));
+
+ /**
+ * {@code minecraft:swamp_hut}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> SWAMP_HUT = create(key("swamp_hut"));
+
+ /**
+ * {@code minecraft:woodland_mansion}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<StructureType> WOODLAND_MANSION = create(key("woodland_mansion"));
+
+ private StructureTypeKeys() {
+ }
+
+ private static @NotNull TypedKey<StructureType> create(final @NotNull Key key) {
+ return TypedKey.create(RegistryKey.STRUCTURE_TYPE, key);
+ }
+}
diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java
new file mode 100644
index 0000000000..bb54110ab1
--- /dev/null
+++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java
@@ -0,0 +1,112 @@
+package io.papermc.paper.registry.keys;
+
+import static net.kyori.adventure.key.Key.key;
+
+import io.papermc.paper.generated.GeneratedFrom;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import net.kyori.adventure.key.Key;
+import org.bukkit.inventory.meta.trim.TrimMaterial;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Vanilla keys for {@link RegistryKey#TRIM_MATERIAL}.
+ *
+ * @apiNote The fields provided here are a direct representation of
+ * what is available from the vanilla game source. They may be
+ * changed (including removals) on any Minecraft version
+ * bump, so cross-version compatibility is not provided on the
+ * same level as it is on most of the other API.
+ */
+@SuppressWarnings({
+ "unused",
+ "SpellCheckingInspection"
+})
+@GeneratedFrom("1.20.2")
+public final class TrimMaterialKeys {
+ /**
+ * {@code minecraft:amethyst}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> AMETHYST = create(key("amethyst"));
+
+ /**
+ * {@code minecraft:copper}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> COPPER = create(key("copper"));
+
+ /**
+ * {@code minecraft:diamond}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> DIAMOND = create(key("diamond"));
+
+ /**
+ * {@code minecraft:emerald}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> EMERALD = create(key("emerald"));
+
+ /**
+ * {@code minecraft:gold}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> GOLD = create(key("gold"));
+
+ /**
+ * {@code minecraft:iron}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> IRON = create(key("iron"));
+
+ /**
+ * {@code minecraft:lapis}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> LAPIS = create(key("lapis"));
+
+ /**
+ * {@code minecraft:netherite}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> NETHERITE = create(key("netherite"));
+
+ /**
+ * {@code minecraft:quartz}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> QUARTZ = create(key("quartz"));
+
+ /**
+ * {@code minecraft:redstone}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimMaterial> REDSTONE = create(key("redstone"));
+
+ private TrimMaterialKeys() {
+ }
+
+ /**
+ * Creates a key for {@link TrimMaterial} in a registry.
+ *
+ * @param key the value's key in the registry
+ * @return a new typed key
+ */
+ @ApiStatus.Experimental
+ public static @NotNull TypedKey<TrimMaterial> create(final @NotNull Key key) {
+ return TypedKey.create(RegistryKey.TRIM_MATERIAL, key);
+ }
+}
diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java
new file mode 100644
index 0000000000..8576ff1669
--- /dev/null
+++ b/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java
@@ -0,0 +1,154 @@
+package io.papermc.paper.registry.keys;
+
+import static net.kyori.adventure.key.Key.key;
+
+import io.papermc.paper.generated.GeneratedFrom;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import net.kyori.adventure.key.Key;
+import org.bukkit.inventory.meta.trim.TrimPattern;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Vanilla keys for {@link RegistryKey#TRIM_PATTERN}.
+ *
+ * @apiNote The fields provided here are a direct representation of
+ * what is available from the vanilla game source. They may be
+ * changed (including removals) on any Minecraft version
+ * bump, so cross-version compatibility is not provided on the
+ * same level as it is on most of the other API.
+ */
+@SuppressWarnings({
+ "unused",
+ "SpellCheckingInspection"
+})
+@GeneratedFrom("1.20.2")
+public final class TrimPatternKeys {
+ /**
+ * {@code minecraft:coast}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> COAST = create(key("coast"));
+
+ /**
+ * {@code minecraft:dune}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> DUNE = create(key("dune"));
+
+ /**
+ * {@code minecraft:eye}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> EYE = create(key("eye"));
+
+ /**
+ * {@code minecraft:host}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> HOST = create(key("host"));
+
+ /**
+ * {@code minecraft:raiser}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> RAISER = create(key("raiser"));
+
+ /**
+ * {@code minecraft:rib}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> RIB = create(key("rib"));
+
+ /**
+ * {@code minecraft:sentry}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> SENTRY = create(key("sentry"));
+
+ /**
+ * {@code minecraft:shaper}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> SHAPER = create(key("shaper"));
+
+ /**
+ * {@code minecraft:silence}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> SILENCE = create(key("silence"));
+
+ /**
+ * {@code minecraft:snout}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> SNOUT = create(key("snout"));
+
+ /**
+ * {@code minecraft:spire}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> SPIRE = create(key("spire"));
+
+ /**
+ * {@code minecraft:tide}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> TIDE = create(key("tide"));
+
+ /**
+ * {@code minecraft:vex}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> VEX = create(key("vex"));
+
+ /**
+ * {@code minecraft:ward}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> WARD = create(key("ward"));
+
+ /**
+ * {@code minecraft:wayfinder}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> WAYFINDER = create(key("wayfinder"));
+
+ /**
+ * {@code minecraft:wild}
+ *
+ * @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ */
+ public static final TypedKey<TrimPattern> WILD = create(key("wild"));
+
+ private TrimPatternKeys() {
+ }
+
+ /**
+ * Creates a key for {@link TrimPattern} in a registry.
+ *
+ * @param key the value's key in the registry
+ * @return a new typed key
+ */
+ @ApiStatus.Experimental
+ public static @NotNull TypedKey<TrimPattern> create(final @NotNull Key key) {
+ return TypedKey.create(RegistryKey.TRIM_PATTERN, key);
+ }
+}
diff --git a/paper-api-generator/src/main/java/io/papermc/generator/Main.java b/paper-api-generator/src/main/java/io/papermc/generator/Main.java
new file mode 100644
index 0000000000..6e02e0b48f
--- /dev/null
+++ b/paper-api-generator/src/main/java/io/papermc/generator/Main.java
@@ -0,0 +1,85 @@
+package io.papermc.generator;
+
+import com.mojang.logging.LogUtils;
+import io.papermc.generator.types.GeneratedKeyType;
+import io.papermc.generator.types.SourceGenerator;
+import io.papermc.paper.registry.RegistryKey;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import net.kyori.adventure.key.Keyed;
+import net.minecraft.SharedConstants;
+import net.minecraft.core.LayeredRegistryAccess;
+import net.minecraft.core.Registry;
+import net.minecraft.core.RegistryAccess;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.resources.RegistryDataLoader;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.server.Bootstrap;
+import net.minecraft.server.RegistryLayer;
+import net.minecraft.server.WorldLoader;
+import net.minecraft.server.packs.PackType;
+import net.minecraft.server.packs.repository.Pack;
+import net.minecraft.server.packs.repository.PackRepository;
+import net.minecraft.server.packs.repository.ServerPacksSource;
+import net.minecraft.server.packs.resources.MultiPackResourceManager;
+import org.apache.commons.io.file.PathUtils;
+import org.bukkit.GameEvent;
+import org.bukkit.block.Biome;
+import org.bukkit.generator.structure.StructureType;
+import org.bukkit.inventory.meta.trim.TrimMaterial;
+import org.bukkit.inventory.meta.trim.TrimPattern;
+import org.slf4j.Logger;
+
+public final class Main {
+
+ private static final Logger LOGGER = LogUtils.getLogger();
+ public static final RegistryAccess.Frozen REGISTRY_ACCESS;
+
+ static {
+ SharedConstants.tryDetectVersion();
+ Bootstrap.bootStrap();
+ final PackRepository resourceRepository = ServerPacksSource.createVanillaTrustedRepository();
+ resourceRepository.reload();
+ final MultiPackResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, resourceRepository.getAvailablePacks().stream().map(Pack::open).toList());
+ LayeredRegistryAccess<RegistryLayer> layers = RegistryLayer.createRegistryAccess();
+ layers = WorldLoader.loadAndReplaceLayer(resourceManager, layers, RegistryLayer.WORLDGEN, RegistryDataLoader.WORLDGEN_REGISTRIES);
+ REGISTRY_ACCESS = layers.compositeAccess().freeze();
+ }
+
+ private static final List<SourceGenerator> GENERATORS = List.of(
+ simpleKey("GameEventKeys", GameEvent.class, Registries.GAME_EVENT, RegistryKey.GAME_EVENT, true),
+ simpleKey("BiomeKeys", Biome.class, Registries.BIOME, RegistryKey.BIOME, true),
+ simpleKey("TrimMaterialKeys", TrimMaterial.class, Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL, true),
+ simpleKey("TrimPatternKeys", TrimPattern.class, Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN, true),
+ simpleKey("StructureTypeKeys", StructureType.class, Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, false)
+ );
+
+ private static <T, A> SourceGenerator simpleKey(final String className, final Class<A> apiType, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey, final boolean publicCreateKeyMethod) {
+ return new GeneratedKeyType<>(className, apiType, "io.papermc.paper.registry.keys", registryKey, apiRegistryKey, publicCreateKeyMethod);
+ }
+
+ private Main() {
+ }
+
+ public static void main(final String[] args) {
+ final Path output = Paths.get(args[0]);
+ try {
+ if (Files.exists(output)) {
+ PathUtils.deleteDirectory(output);
+ }
+ Files.createDirectories(output);
+
+ for (final SourceGenerator generator : GENERATORS) {
+ generator.writeToFile(output);
+ }
+
+ LOGGER.info("Files written to {}", output.toAbsolutePath());
+ } catch (final Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+
+}
diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java b/paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java
new file mode 100644
index 0000000000..342d80454b
--- /dev/null
+++ b/paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java
@@ -0,0 +1,24 @@
+package io.papermc.generator.types;
+
+import com.squareup.javapoet.AnnotationSpec;
+import java.util.List;
+import org.bukkit.MinecraftExperimental;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+public final class Annotations {
+
+ public static final List<AnnotationSpec> EXPERIMENTAL_ANNOTATIONS = List.of(
+ AnnotationSpec.builder(ApiStatus.Experimental.class).build(),
+ AnnotationSpec.builder(MinecraftExperimental.class)
+ .addMember("value", "$S", "update 1.20")
+ .build()
+ );
+
+ @ApiStatus.Experimental
+ public static final AnnotationSpec EXPERIMENTAL_API_ANNOTATION = AnnotationSpec.builder(ApiStatus.Experimental.class).build();
+ public static final AnnotationSpec NOT_NULL = AnnotationSpec.builder(NotNull.class).build();
+
+ private Annotations() {
+ }
+}
diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java
new file mode 100644
index 0000000000..2af1bc8fb6
--- /dev/null
+++ b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java
@@ -0,0 +1,205 @@
+package io.papermc.generator.types;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import io.papermc.generator.Main;
+import io.papermc.generator.utils.CollectingContext;
+import io.papermc.paper.generated.GeneratedFrom;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.TypedKey;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import net.kyori.adventure.key.Key;
+import net.minecraft.SharedConstants;
+import net.minecraft.core.Registry;
+import net.minecraft.core.RegistrySetBuilder;
+import net.minecraft.resources.ResourceKey;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.DefaultQualifier;
+
+import static com.squareup.javapoet.TypeSpec.classBuilder;
+import static io.papermc.generator.types.Annotations.EXPERIMENTAL_ANNOTATIONS;
+import static io.papermc.generator.types.Annotations.EXPERIMENTAL_API_ANNOTATION;
+import static io.papermc.generator.types.Annotations.NOT_NULL;
+import static java.util.Objects.requireNonNull;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+
+@DefaultQualifier(NonNull.class)
+public class GeneratedKeyType<T, A> implements SourceGenerator {
+
+ // don't exist anymore
+ // private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> EXPERIMENTAL_REGISTRY_ENTRIES = UpdateOneTwentyRegistries.BUILDER.entries.stream()
+ // .collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap));
+ private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> EXPERIMENTAL_REGISTRY_ENTRIES = Collections.emptyMap();
+
+ private static final Map<RegistryKey<?>, String> REGISTRY_KEY_FIELD_NAMES;
+ static {
+ final Map<RegistryKey<?>, String> map = new HashMap<>();
+ try {
+ for (final Field field : RegistryKey.class.getFields()) {
+ if (!Modifier.isStatic(field.getModifiers()) || !Modifier.isFinal(field.getModifiers()) || field.getType() != RegistryKey.class) {
+ continue;
+ }
+ map.put((RegistryKey<?>) field.get(null), field.getName());
+ }
+ REGISTRY_KEY_FIELD_NAMES = Map.copyOf(map);
+ } catch (final ReflectiveOperationException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static final AnnotationSpec SUPPRESS_WARNINGS = AnnotationSpec.builder(SuppressWarnings.class)
+ .addMember("value", "$S", "unused")
+ .addMember("value", "$S", "SpellCheckingInspection")
+ .build();
+ private static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class)
+ .addMember("value", "$S", SharedConstants.getCurrentVersion().getName())
+ .build();
+ private static final String TYPE_JAVADOC = """
+ Vanilla keys for {@link $T#$L}.
+
+ @apiNote The fields provided here are a direct representation of
+ what is available from the vanilla game source. They may be
+ changed (including removals) on any Minecraft version
+ bump, so cross-version compatibility is not provided on the
+ same level as it is on most of the other API.
+ """;
+ private static final String FIELD_JAVADOC = """
+ {@code $L}
+
+ @apiNote This field is version-dependant and may be removed in future Minecraft versions
+ """;
+ private static final String CREATE_JAVADOC = """
+ Creates a key for {@link $T} in a registry.
+
+ @param key the value's key in the registry
+ @return a new typed key
+ """;
+
+ private final String keysClassName;
+ private final Class<A> apiType;
+ private final String pkg;
+ private final ResourceKey<? extends Registry<T>> registryKey;
+ private final RegistryKey<A> apiRegistryKey;
+ private final boolean publicCreateKeyMethod;
+
+ public GeneratedKeyType(final String keysClassName, final Class<A> apiType, final String pkg, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey, final boolean publicCreateKeyMethod) {
+ this.keysClassName = keysClassName;
+ this.apiType = apiType;
+ this.pkg = pkg;
+ this.registryKey = registryKey;
+ this.apiRegistryKey = apiRegistryKey;
+ this.publicCreateKeyMethod = publicCreateKeyMethod;
+ }
+
+ private MethodSpec.Builder createMethod(final TypeName returnType) {
+ final TypeName keyType = TypeName.get(Key.class).annotated(NOT_NULL);
+
+ final ParameterSpec keyParam = ParameterSpec.builder(keyType, "key", FINAL).build();
+ final MethodSpec.Builder create = MethodSpec.methodBuilder("create")
+ .addModifiers(this.publicCreateKeyMethod ? PUBLIC : PRIVATE, STATIC)
+ .addParameter(keyParam)
+ .addCode("return $T.create($T.$L, $N);", TypedKey.class, RegistryKey.class, requireNonNull(REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey), "Missing field for " + this.apiRegistryKey), keyParam)
+ .returns(returnType.annotated(NOT_NULL));
+ if (this.publicCreateKeyMethod) {
+ create.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO remove once not experimental
+ create.addJavadoc(CREATE_JAVADOC, this.apiType);
+ }
+ return create;
+ }
+
+ private TypeSpec.Builder keyHolderType() {
+ return classBuilder(this.keysClassName)
+ .addModifiers(PUBLIC, FINAL)
+ .addJavadoc(TYPE_JAVADOC, RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey))
+ .addAnnotation(SUPPRESS_WARNINGS).addAnnotation(GENERATED_FROM)
+ .addMethod(MethodSpec.constructorBuilder()
+ .addModifiers(PRIVATE)
+ .build()
+ );
+ }
+
+ protected TypeSpec createTypeSpec() {
+ final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType);
+
+ final TypeSpec.Builder typeBuilder = this.keyHolderType();
+ typeBuilder.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO experimental API
+ final MethodSpec.Builder createMethod = this.createMethod(typedKey);
+
+ final Registry<T> registry = Main.REGISTRY_ACCESS.registryOrThrow(this.registryKey);
+ final List<ResourceKey<T>> experimental = this.collectExperimentalKeys(registry);
+
+ boolean allExperimental = true;
+ for (final T value : registry) {
+ final ResourceKey<T> key = registry.getResourceKey(value).orElseThrow();
+ final String keyPath = key.location().getPath();
+ final String fieldName = keyPath.toUpperCase(Locale.ENGLISH).replaceAll("[.-/]", "_"); // replace invalid field name chars
+ final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
+ .initializer("$N(key($S))", createMethod.build(), keyPath)
+ .addJavadoc(FIELD_JAVADOC, key.location().toString());
+ if (experimental.contains(key)) {
+ fieldBuilder.addAnnotations(EXPERIMENTAL_ANNOTATIONS);
+ } else {
+ allExperimental = false;
+ }
+ typeBuilder.addField(fieldBuilder.build());
+ }
+ if (allExperimental) {
+ typeBuilder.addAnnotations(EXPERIMENTAL_ANNOTATIONS);
+ createMethod.addAnnotations(EXPERIMENTAL_ANNOTATIONS);
+ }
+ return typeBuilder.addMethod(createMethod.build()).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<ResourceKey<T>> collectExperimentalKeys(final Registry<T> registry) {
+ final RegistrySetBuilder.@Nullable RegistryBootstrap<T> registryBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) EXPERIMENTAL_REGISTRY_ENTRIES.get(this.registryKey);
+ if (registryBootstrap == null) {
+ return Collections.emptyList();
+ }
+ final List<ResourceKey<T>> experimental = new ArrayList<>();
+ final CollectingContext<T> context = new CollectingContext<>(experimental, registry);
+ registryBootstrap.run(context);
+ return experimental;
+ }
+
+ protected JavaFile createFile() {
+ return JavaFile.builder(this.pkg, this.createTypeSpec())
+ .skipJavaLangImports(true)
+ .addStaticImport(Key.class, "key")
+ .indent(" ")
+ .build();
+ }
+
+ @Override
+ public final String outputString() {
+ return this.createFile().toString();
+ }
+
+ @Override
+ public void writeToFile(final Path parent) throws IOException {
+ final Path pkgDir = parent.resolve(this.pkg.replace('.', '/'));
+ Files.createDirectories(pkgDir);
+ Files.writeString(pkgDir.resolve(this.keysClassName + ".java"), this.outputString(), StandardCharsets.UTF_8);
+ }
+}
diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java b/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java
new file mode 100644
index 0000000000..50d176e9ea
--- /dev/null
+++ b/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java
@@ -0,0 +1,11 @@
+package io.papermc.generator.types;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public interface SourceGenerator {
+
+ String outputString();
+
+ void writeToFile(Path parent) throws IOException;
+}
diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java
new file mode 100644
index 0000000000..98f707846e
--- /dev/null
+++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/CollectingContext.java
@@ -0,0 +1,28 @@
+package io.papermc.generator.utils;
+
+import com.mojang.serialization.Lifecycle;
+import io.papermc.generator.Main;
+import java.util.List;
+import net.minecraft.core.Holder;
+import net.minecraft.core.HolderGetter;
+import net.minecraft.core.Registry;
+import net.minecraft.data.worldgen.BootstapContext;
+import net.minecraft.resources.ResourceKey;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.framework.qual.DefaultQualifier;
+
+@DefaultQualifier(NonNull.class)
+public record CollectingContext<T>(List<ResourceKey<T>> registered,
+ Registry<T> registry) implements BootstapContext<T> {
+
+ @Override
+ public Holder.Reference<T> register(final ResourceKey<T> resourceKey, final @NonNull T t, final Lifecycle lifecycle) {
+ this.registered.add(resourceKey);
+ return Holder.Reference.createStandAlone(this.registry.holderOwner(), resourceKey);
+ }
+
+ @Override
+ public <S> HolderGetter<S> lookup(final ResourceKey<? extends Registry<? extends S>> resourceKey) {
+ return Main.REGISTRY_ACCESS.registryOrThrow(resourceKey).asLookup();
+ }
+}
diff --git a/paper-api-generator/wideners.at b/paper-api-generator/wideners.at
new file mode 100644
index 0000000000..cc899edd9d
--- /dev/null
+++ b/paper-api-generator/wideners.at
@@ -0,0 +1,6 @@
+accessWidener v1 named
+accessible method net/minecraft/server/WorldLoader loadAndReplaceLayer (Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/core/LayeredRegistryAccess;Lnet/minecraft/server/RegistryLayer;Ljava/util/List;)Lnet/minecraft/core/LayeredRegistryAccess;
+
+# for auto-marking experimental stuff
+accessible field net/minecraft/core/RegistrySetBuilder entries Ljava/util/List;
+accessible class net/minecraft/core/RegistrySetBuilder$RegistryStub