|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Fabric for Minecraft 1.21.5 |
| 4 | +ref: 1215 |
| 5 | +--- |
| 6 | +A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, **we ask all players to be patient, and give mod developers time to update to this new version.** We kindly ask everyone not to pester them. **We also recommend all players make backups of their worlds.** |
| 7 | + |
| 8 | +Here is a list of several major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names. |
| 9 | + |
| 10 | +## Fabric changes |
| 11 | +Developers should use Loom 1.10 (at the time of writing) to develop mods for Minecraft 1.21.5. Players should install the latest stable version of Fabric Loader (currently 0.16.10). |
| 12 | + |
| 13 | +### Loom 1.10 |
| 14 | +Loom 1.10 requires Gradle 8.12, and comes with performance improvements and enhanced testing setup support. You can checkout the new Loom documentation [here](https://docs.fabricmc.net/develop/loom/). |
| 15 | + |
| 16 | +### Deprecations and removals |
| 17 | +In Content Registries, `VillagerInteractionsRegistries#registerGiftLootTable` overload that takes an `Identifier` was removed. This method was previously deprecated. |
| 18 | + |
| 19 | +In Object Builder, two deprecated classes, namely `VillagerProfessionBuilder` and `VillagerTypeHelper`, have been removed. Use the `VillagerProfession` constructor and `VillagerType#create` instead. `TradeOfferHelper#refreshOffers`, which had been deprecated and did nothing, was also removed. |
| 20 | + |
| 21 | +`HudRenderCallback` has been deprecated in favor of newly added `HudLayerRegistrationCallback`. |
| 22 | + |
| 23 | +### Breaking changes |
| 24 | +When a mod creates a new dynamic registry, the data pack JSON files for the registry must now be placed inside namespaced directories. For example, if the new registry is `example:potato_variant`, the file for variant `test:tiny` will be placed in `data/test/example/potato_variant/tiny.json`.<!-- https://github.com/FabricMC/fabric/pull/4180 --> |
| 25 | + |
| 26 | +`BiomeModificationContext#addSpawn` has a new parameter, `weight`. This was previously part of `SpawnEntry`. |
| 27 | + |
| 28 | +`TradeOfferHelper` now takes a `RegistryKey` of the profession instead of `VillagerProfession`. Wandering trader trades must now be added via the builder, which was previously used for the Rebalance experiment. (The rebalanced trades are now used in all worlds.) |
| 29 | + |
| 30 | +### New Fabric API changes |
| 31 | +With the help of many contributors, Fabric API has received some new features since the last update blog post: |
| 32 | + |
| 33 | +- New module: Client Game Test API, which can be used to automatically test client rendering and GUI (Earthcomputer) |
| 34 | +- New module: Fabric Tag API, which currently handles tag aliases (Juxxel) |
| 35 | +- Convention Tags: Sync remaining `c` tags with NeoForge (TelepathicGrunt) |
| 36 | +- Convention Tags: Add `c:flowers`, `c:flowers/tall`, and `c:flowers/small` block and item tags (TelepathicGrunt) |
| 37 | +- Convention Tags: Add `TagKey` for `c:tools/wrench` (TelepathicGrunt) |
| 38 | +- Convention Tags: Convention Drink Tags (TheDeathlyCow) |
| 39 | +- Convention Tags: Add Pumpkin Block and Item Tags (JT122406) |
| 40 | +- Data Generation: Add vararg helper methods for multi-tag support in `FabricTagBuilder` (Starexify) |
| 41 | +- Data Generation: Add `FabricEntityLootTableProvider` (Antikyth) |
| 42 | +- Item API: Add a method for overriding modelId in item settings (Patbox) |
| 43 | +- Item API: Add `contains` method to `FabricComponentMapBuilder` (TheDeathlyCow) |
| 44 | +- Item Group API: Change Creative Buttons Texture (matthewperiut) |
| 45 | +- Item Group API: Use page up/down to change creative inventory pages (modmuss50) |
| 46 | +- Model Loading API: Allow retrieving model loading plugins (PepperCode1) |
| 47 | +- Networking API: Add `ServerPlayNetworking.reconfigure` (modmuss50) |
| 48 | +- Object Builder: Allow setting `canPotentiallyExecuteCommands` in builders (PepperCode1) |
| 49 | +- Recipe API: Add `getAllMatches` and `getAllOfType` methods to `ServerRecipeManager` (Patbox) |
| 50 | +- Registry Sync: Add `RegistryAttribute#OPTIONAL` that can be used to not disconnect clients lacking an entire registry; note that optional registry values are still unsupported (modmuss50) |
| 51 | +- Registry Sync: Registry aliasing (Syst3ms) |
| 52 | +- Rendering: Add `SpecialBlockRendererRegistry` (PepperCode1) |
| 53 | +- Rendering: Add HUD Render Events (kevinthegreat1) |
| 54 | +- Resource Loader: Implement builtin mod resource/data pack sorting (Apollo) |
| 55 | + |
| 56 | +### Tag and registry aliases |
| 57 | +The new tag and registry alias APIs allow for mods to seemlessly migrate their tags and registry aliases to new names. Thanks to Juuxel and Syst3ms respectively for implementing these new APIs. |
| 58 | + |
| 59 | +```java |
| 60 | +Registries.BLOCK.addAlias(Identifier.of("my_mod", "old"), Registries.BLOCK.get(Identifier.of("my_mod", "new"))); |
| 61 | +``` |
| 62 | +Registry aliases are really simple; with the code above, any access to the old ID in the registry is redirected to the new ID. This allows worlds to be upgraded to use the new ID; for example, a block with the old ID becomes the one with the new ID. |
| 63 | + |
| 64 | +Tag aliases are defined in data packs like tags. For example, a block tag alias group for fences would be located at `data/my_mod/fabric/tag_aliases/block/fences.json` with the contents: |
| 65 | + |
| 66 | +```json |
| 67 | +{ |
| 68 | + "tags": [ |
| 69 | + "minecraft:fences", |
| 70 | + "c:fences" |
| 71 | + ] |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +### Client GameTest |
| 76 | +For a long time, Fabric has had an internal client test framework that was used for testing that Fabric API was working correctly on the client. In a series of PRs, Earthcomputer has worked to expand and expose this framework to mod developers. The new experimental API has the following features: |
| 77 | +- World creation API, for specifying options used to generate the test world. |
| 78 | +- Screenshot API, with support for comparing against golden images. |
| 79 | +- Input API, to simulate a user interacting with the game. |
| 80 | +- Advanced threading setup, to make the tests more repoducible. |
| 81 | +- Network synchronization, to ensure packets are handled consistently. |
| 82 | +- Herobrine removal, to bring peace to the Kingdom of Tiny Potato. |
| 83 | + |
| 84 | +For more information checkout the full documentation [here](https://maven.fabricmc.net/docs/fabric-api-0.119.2+1.21.5/net/fabricmc/fabric/api/client/gametest/v1/package-summary.html). |
| 85 | + |
| 86 | +### HUD Render Events |
| 87 | +Fabric API 0.116.0 added `HudLayerRegistrationCallback` event, providing full control over the HUD rendering process. The new API assigns idenftifiers to each layer that can be used to specify where things will be rendered. The new API also allows replacing or removing existing layers. A big thanks to kevinthegreat1 and many other people for making this happen! |
| 88 | + |
| 89 | +## Minecraft changes |
| 90 | +### NBT |
| 91 | +Significant changes to NBT handling code have been made. |
| 92 | + |
| 93 | +`NbtCompound` methods now return `Optional` instead of the value. If the key is not in the compound or if the value is not of the correct type, an empty optional is now returned instead of that type's default value. |
| 94 | + |
| 95 | +```diff |
| 96 | +- int value = nbt.getInt("value"); |
| 97 | ++ Optional<Integer> value = nbt.getInt("value"); // not OptionalInt |
| 98 | +``` |
| 99 | + |
| 100 | +For primitives (numbers and strings), instead of checking for the existence of a key and handling a fallback, the fallback can now be passed to `get` methods: |
| 101 | + |
| 102 | +```diff |
| 103 | +- int value; |
| 104 | +- if (nbt.contains("value", NbtElement.NUMBER_TYPE)) { |
| 105 | +- value = nbt.getInt("value"); |
| 106 | +- } else { |
| 107 | +- value = 1000; |
| 108 | +- } |
| 109 | ++ int value = nbt.getInt("value", 1000); |
| 110 | +``` |
| 111 | + |
| 112 | +Also note that `NbtElement#NUMBER_TYPE` and type-aware `contains` have been removed. There is no fallback method for `getIntArray`, `getLongArray`, and `getByteArray`. (Use `Optional#orElse`.) |
| 113 | + |
| 114 | +For `getCompound` and `getList` methods, methods with the previous behavior (returning empty objects) are provided with `OrEmpty` suffix. |
| 115 | + |
| 116 | +```diff |
| 117 | +- NbtCompound config = nbt.getCompound("config"); |
| 118 | ++ NbtCompound config = nbt.getCompoundOrEmpty("config"); |
| 119 | +``` |
| 120 | + |
| 121 | +Finally, for those who want to encode/decode codec-based values (such as `Identifier`) stored in a `NbtCompound` field, new methods simplify the process: |
| 122 | + |
| 123 | +```java= |
| 124 | +NbtCompound nbt = new NbtCompound(); |
| 125 | +nbt.put("Id", Identifier.CODEC, id); |
| 126 | +// for reading |
| 127 | +Optional<Identifier> id = nbt.get("Id", Identifier.CODEC); |
| 128 | +``` |
| 129 | + |
| 130 | +And if there is a codec for the whole object: |
| 131 | +```java= |
| 132 | +NbtCompound nbt = new NbtCompound(); |
| 133 | +// have to use the RegistryOps since an item is a registry entry |
| 134 | +nbt.copyFromCodec(ItemStack.MAP_CODEC, wrapperLookup.getOps(NbtOps.INSTANCE), stack); |
| 135 | +// for reading |
| 136 | +Optional<ItemStack> stack = nbt.decode(ItemStack.MAP_CODEC, wrapperLookup.getOps(NbtOps.INSTANCE)); |
| 137 | +``` |
| 138 | + |
| 139 | +Typed arrays (`ByteArray`, `IntArray`, and `LongArray`) are no longer `List`s. They can be converted to a list using `.stream().toList()`, but this is usually not necessary. `NbtList` can now contain values of differing types, but this should be a transparent change unless you work with binary data. |
| 140 | + |
| 141 | +### GameTest |
| 142 | + |
| 143 | +In Minecraft [25w03a](https://www.minecraft.net/en-us/article/minecraft-snapshot-25w03a), Mojang totally refactored the vanilla testing framework, exposing it to datapack developers. Unfortunately, the new API is a little bit cumbersome for mod developers. Fabric API now provides its own `@GameTest` annotation that functions similarly to the old one. The options in the new Fabric-provided `@GameTest` annotation directly map the vanilla data-driven options, removing the need to have a JSON file for each test function. Data driven tests will still work if you wish to use the vanilla system. |
| 144 | + |
| 145 | +### Miscellaneous |
| 146 | +- `DataPool` has been replaced with `Pool`. |
0 commit comments