Minecraft 1.21.5
These migration notes cover only the changes made to Balm APIs.
For Minecraft and mod-loader specific migrations, check out their respective release announcements or primers.
Overview
In Minecraft 1.21.5, Balm has removed some long-standing deprecations, and refactored the way configs and capabilities are handled.
⚠️ Known Issues
Extra Models are missing on Fabric
Fabric has not yet re-added the API for loading extra models. Balm defaults to the missing model so your code can at least run without crashing.
/balm export icons
is not yet functional
The command has not yet been updated to Minecraft's rendering changes.
Notable Additions and Changes
BalmModule
and BalmClientModule
, an alternative way to initialize your mods
Modules are a slightly cleaner way of interacting with Balm, where instead of accessing Balm services through the Balm
helper class in your initializer, you instead override the appropriate register*
method in your module and have it called by Balm at the appropriate time.
Read through the Modules documentation to learn more.
BalmConfigSchema
for Declarative Configs
Configs have been refactored for a much cleaner and more stable code-base, while also adding the ability to define a configuration programmatically instead of only statically through annotations.
The previous annotation-based approach is still present and will remain, however some packages and annotations have been renamed for clarity.
Balm now also supports different config types, although only common
and client
are universally supported across all mod loaders.
The changes to BalmConfig
and Declarative Configs have been backported to 1.20.1, 1.21.1 and 1.21.4.
SyncConfigMessage
has been removed
Balm now automatically takes care of syncing mod's configs through its own packet. Mods no longer need to register a packet of their own.
Added BalmConfigSchema
as an alternative way to define configs
Configs are now no longer directly tied to a given data class. Instead, their structure is defined in a schema, very similar to how config specs are built in Forge and NeoForge.
However, the annotation-based approach remains and will continue to function. Schemas will be auto-generated for annotation-based configs so both can use the same code in the back.
Read through the Mod Configurations documentation for more information.
Renamed some packages for annotation-based configs
Annotations such as @Config
, @Comment
and @Synced
are now available under the package net.blay09.mods.balm.api.config.reflection
.
ExpectedType
has been renamed to NestedType
The new name makes it more clear that the annotation is meant to be used for collections / generics.
BalmConfigData
has been removed
The interface served no purpose beyond slightly better type-safety.
Since mods generally only access their config classes in two places (registerConfig
and getActiveConfig
) where errors are easy to notice, the interface has been removed for simplicity.
BalmCapabilities
replaces BalmProviders
The previous BalmProviders
implementation was heavily biased towards Forge's approach to capabilities and had several shortcomings that resulted in a lot of mod-loader-specific boilerplate. It has been removed in favor the new BalmCapabilities
service.
With this new service, it is now possible to universally register capabilities, capability providers, and fallback providers through Balm.
Read through the Capabilities documentation for more information.
The new BalmCapabilities
service has been backported to 1.20.1, 1.21.1 and 1.21.4.
Minor Changes
BalmModels.loadModel
now returns a BlockStateModel
BlockStateModel
can be used in the same manner that BakedModel
was, with the difference that you must use collectParts(RandomSource)
to pass them into the tesselateBlock
method.
Extra Models are not currently supported on Fabric. They will always return the missing model.
BalmRenderers
and BalmScreens
registration methods now require a ResourceLocation
identifier
While this identifier is not technically used by Minecraft or mod loaders, Balm needs it to attribute your objects to the appropriate mod.
As a side-effect, this should also be more future-proof since more and more things are moving to registries or at least being identifiable.
FluidTank
and EnergyStorage
are now an interface
An interface was added as to not limit the respective Balm capabilities to only Balm's default implementation.
In return, the default implementation has been renamed to DefaultFluidTank
and DefaultEnergyStorage
.
If you are querying for a FLUID_TANK
or ENERGY_STORAGE
capability, you should handle the interface under the same name as previously.
If you are defining your own fluid tank or energy storage, you should use DefaultFluidTank
and DefaultEnergyStorage
or a custom implementation.
isConnectedToServer
has been renamed to isConnected
This method is available through Balm.getProxy()
and can be used before sending packets to ensure they are only sent if the player is actually ingame.
This was changed to avoid confusion on what this method does. Unlike the previous name may have suggested, it is not the equivalent of an isMultiplayer()
method.
isConnected
checks if the client is connected to any server, be it the integrated singleplayer server, a LAN server, or a dedicated server.
Caveats
Balm.registerConfig
may not load your config immediately anymore
On Forge and NeoForge, common
and client
configs are no longer immediately available. Accessing the config in your initializer will result in a crash. You can instead use the new ConfigLoadedEvent
to act only once the config is available.
However, that may be too late if you need access to the configuration for e.g. setting up item components. There is no good universal solution to this as of now.
This was the case all the way back to 1.20.1, but it was not as noticeable because Balm would simply return the default values for a configuration.
Newer versions of Balm will crash if the config is accessed too early.
Reload Listeners can no longer be added directly to ReloadableResourceManager
Adding reload listeners to the ReloadableResourceManager
directly is no longer supported, as NeoForge had made the list immutable in favor of their registration event.
Balm now provides an addResourceReloadListener
method that uses the proper channels to register the listener on each mod loader.
Functionally, this method behaves the same as registering a reload listener directly used to.
Removals
Removals in BalmBlocks
blockProperties()
has been removed
Block Properties now require an identifier to be set, and mod-loader specific BlockBehaviour.Properties
no longer exist, making this method obsolete. Instead, there is now a static blockProperties(ResourceLocation)
utility method you can use.
registerBlock(Supplier, ResourceLocation)
has been removed
Use registerBlock(Function, ResourceLocation)
instead, which gives you access to the identifier you passed in (since you'll need it to construct your block properties).
registerBlockItem(Supplier, ResourceLocation)
and registerBlockItem(Supplier, ResourceLocation, ResourceLocation)
has been removed
Use registerBlockItem(Function, ResourceLocation)
or registerBlockItem(Function, ResourceLocation, ResourceLocation)
instead, which gives you access to the identifier you passed in (since you'll need it to construct your item properties).
register(Supplier, Supplier, ResourceLocation)
and register(Supplier, Supplier, ResourceLocation, ResourceLocation)
has been removed
Use register(Function, BiFunction, ResourceLocation)
or register(Function, BiFunction, ResourceLocation, ResourceLocation)
instead, which gives you access to the identifier you passed in, since you'll need it to construct your block and item properties.
Additionally, the BiFunction
for your block item also gets the constructed block passed in, simplifying registration further.
Removals in BalmItems
itemProperties()
has been removed
Item Properties now require an identifier to be set, and mod-loader specific Item.Properties
no longer exist, making this method obsolete. Instead, there is now a static itemProperties(ResourceLocation)
utility method you can use.
registerItem(Supplier, ResourceLocation)
and registerItem(Supplier, ResourceLocation, ResourceLocation)
has been removed
Use registerItem(Function, ResourceLocation)
or registerItem(Function, ResourceLocation, ResourceLocation)
instead, which gives you access to the identifier you passed in (since you'll need it to construct your item properties).
Removals in BalmNetworking
openGui
has been removed in favor of openMenu
The new method name more accurately describes what the method does and is functionally identical.
registerClientboundPacket
that takes Consumer
and Function
for encoding and decoding has been removed
Minecraft is migrating its network protocol to use StreamCodec
s, which are a composable way of declaring the structure of the data that gets sent and received.
You can still use StreamCodec.of(encoder, decoder)
to create a StreamCodec
with imperative code, although it is recommended to migrate to using StreamCodec.composite(...)
, as this declarative approach is less error-prone.
Removals in BalmHooks
getBurnTime
has been removed
You can instead use level.fuelValues().burnDuration(itemStack)
.
isShield
has been removed
You can instead check for the DataComponents.BLOCKS_ATTACKS
data components.
isRepairable
has been removed
You can instead check for the DataComponents.REPAIRABLE
or DataComponents.REPAIR_COST
data components.
getBlockReachDistance
has been removed
You can instead query the Attributes.BLOCK_INTERACTION_RANGE
attribute.
Removals in BalmRegistries
getKey
, getItemKeys
and getItem
/... has been removed
These methods are all available through the respective registry in BuiltinRegistries
instead.
getItemTag
has been removed
You can instead easily create a TagKey<Item>
yourself:
TagKey<Item> yourTag = TagKey.create(Registries.ITEM, yourResourceLocation);
Removals in BalmKeyMappings
Registration methods taking KeyConflictContext
and KeyModifier
have been removed
Kuma is the preferred solution for dealing with special key mappings, which allows defining defaults as well as fallbacks should key modifiers not be supported by the mod loader.
Kuma is already embedded in Balm, so you can safely depend on it without needing to jar-in-jar it.
Modifier- and Context-aware isActive*
methods have been removed
Since Balm no longer provides the functionality for key conflict contexts and modifiers, you can now just use the existing methods from the KeyMapping
to check for its state.
If you use Kuma, you can access the state on the ManagedKeyMapping
, or use the event handlers when registering your keys to define your logic.
ignoreConflicts(KeyMapping)
and related methods have been removed
These methods were added to allow configuring key modifiers through dummy key mappings, but they were never really functional due to Minecraft's limitation of only supporting an input to be bound to a single key. In prior Balm versions, these methods already no-op'ed.
KeyConflictContext
, KeyModifier
and KeyModifiers
have been removed
If you were using these classes, you should instead use Kuma or define your own.
Removals in BalmRecipes
registerRecipeType
that takes both RecipeType and RecipeSerializer has been removed
Use registerRecipeType
and registerRecipeSerializer
individually instead.
Removal of BalmTextures
This class was already empty and has not been needed for a while, since custom textures can be added to atlases through resource packs.
Removal of ExtractionAwareContainer
This interface was highly incompatible with other mods as the extraction checks were only performed when Balm's own ContainerUtils
were used.
Instead, you should implement Vanilla's Container.canTakeItem
or WorldlyContainer.canTakeItemThroughFace
in your container.