Minecraft 26.2 -> 26.3 Mod Migration Primer
This is a high level, non-exhaustive overview on how to migrate your mod from 26.2 to 26.3. This does not look at any specific mod loader, just the changes to the vanilla classes. All provided names use the official mojang mappings.
This primer is licensed under the Creative Commons Attribution 4.0 International, so feel free to use it as a reference and leave a link so that other readers can consume the primer.
If there's any incorrect or missing information, please file an issue on this repository or ping @ChampionAsh5357 in the Neoforged Discord server.
Thank you to:
- @RogueLogix for reviews on the Blaze3d and Renderpearl changes
- @crendgrim since the E key is not the M key
Pack Changes
There are a number of user-facing changes that are part of vanilla which are not discussed below that may be relevant to modders. You can find a list of them on Misode's version changelog.
There's Always a Client Rewrite
LWJGL with SDL
The Lightweight Java Game Library (LWJGL) now ships with Simple DirectMedia Layer (SDL) instead of the Graphics Library Framework (GLFW). As such, most of the backend logic that called out to GLFW has either been completely removed or refashioned to use SDL method calls.
The most common changes visible to users involve handling input from the keyboard and mouse.
The associated input codes now have different values. To remap these scancodes, you should either use the constants defined in InputConstants or SDLScancode:
new KeyMapping(
"examplemod.key.example_key",
// The SDL scancode to capture when pressed.
InputConstants.KEY_M, // or SDLScancode#SDL_SCANCODE_M
KeyMapping.Category.MISC
);
Note that we are now using the scancode as our 'key' with SDL instead of the logical key from GLFW. These both function equivalently, as GLFW keys are known as scancodes in SDL, while GLFW scancodes refer to SDL keycodes.
For KeyEvent, this means that key refers to the values from SDLScancode, and keycode (renamed from scancode) refers to the values from SDLKeycode. MouseButtonInfo#button reference the SDLMouse#SDL_BUTTON_* constants. As for the input modifiers (e.g., lctrl, rshift), they are a mask of the SDLKeycode#SDL_KMOD_* constants.
The other important change is how text input is handled. Due to the differences in how GLFW and SDL setup the callbacks, SDL requires SDLKeyboard#SDL_StartTextInput and SDL_StopTextInput to know when the player is typing. Vanilla implements these through TextInputManager#startTextInput and stopTextInput, taking in the object consuming the input. For use in GUIs, vanilla calls TextureInputManager#onTextInputFocusChange through Minecraft#onTextInputFocusChange to manage GUI element selection and focusing, while also handling any preedit events.
As such, modders must make sure to call TextureInputManager#onTextInputFocusChange whenever the player should start or stop typing. For GUI elements, this should be within GuiEventListener#setFocused at a minimum:
// For some basic gui element
public class ExampleWidget extends AbstractWidget {
// ...
@Override
public void setFocused(boolean focused) {
super.setFocused(focused);
// Change the input focus.
// This may need to be called in other places depending on
// how your text input element is handled.
// You can also call the following instead if outside a GUI context:
// Minecraft.getInstance().textInputManager().onTextInputFocusChange(this, focused);
Minecraft.getInstance().onTextInputFocusChange(this, focused);
}
}
Renderpearl
The render API that previously lived in Blaze3d has been split into a separate project called Renderpearl. All rendering classes that originally lived in Blaze3d have been migrated to com.mojang.renderpearl.
Packages in Renderpearl are roughly structured like so:
com.mojang.renderpearl.api.*- APIs for the elements the vanilla game interacts with.com.mojang.renderpearl.backend.*- The objects that manage the actual logic to communicate with a graphics library.com.mojang.renderpearl.frontend.*- The implemented APIs that the vanilla game interacts with. These classes handle most of the validation.
No More Texture Override Shenanigans
RenderSystem#outputColorTextureOverride and outputDepthTextureOverride have been fully removed, closing one of the shenanigans then it came to writing to the GPU texture, especially for FeatureRenderDispatcher. Now, each try-with-resources creates the RenderPass to specify the textures to output to, along with any other information, like the FeatureRenderDispatcher$PreparedFrame:
// Setup everything possible before the render frame
// Create the texture to write to
GpuDevice device = RenderSystem.getDevice();
GpuTexture texture = device.createTexture(/*...*/);
GpuTexture textureView = device.createTextureView(texture);
GpuTexture depthTexture = device.createTexture(/*...*/);
GpuTexture depthTextureView = device.createTextureView(depthTexture);
device.createCommandEncoder().clearColorAndDepthTextures(texture, new Vector4f(0f), depthTexture, 0);
// ...
// Write data for rendering
SubmitNodeStorage storage = new SubmitNodeStorage();
storage.submitCustomGeometry(/*...*/);
// ...
// Render to the texture.
// This should only contain those critical to modify the render pass with
// the correct info. Everything else should've been done prior.
try (
FeatureRenderDispatcher.PreparedFrame frame = featureRenderDispatcher.prepareFrame(storage);
RenderPass pass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(() -> "Example", textureView, Optional.empty(), depthTextureView, OptionalDouble.empty());
) {
// Setup anything required by the pass.
RenderSystem.bindDefaultUniforms(pass);
//...
// Render to the textures.
FeatureRenderDispatcher.renderAllFeatures(pass, frame);
}
Shader Extensions and Layouts
The Shader GLSL now has some additional features and changes regarding the the underlying syntax as Shaderc is now used for compilation on both OpenGL and Vulkan via the GlslCompiler.
As such, #moj_import was renamed to #include to import functions from other shaders. Additionally, both the in and out uniforms must specify their location in the layout to maintain a fixed read/write location when passing from vertex to fragment. This is especially valuable when some are included based on shader defines.
Speaking of defines, GlslCompiler provides three macros: RENDERPEARL_DEPTH_IS_ZERO_TO_ONE for if the device coordinates are between 0-1 (always defined for Vulkan, if the machine has the GL_ARB_clip_control extension for OpenGL), RENDERPEARL_EXPLICIT_DEPTH_INVARIANCE for if the depth must be explicitly set (currently only Apple silicon machines), and RENDERPEARL_INSTANCE_INDEX_INCLUDES_BASE_INSTANCE for if the gl_InstanceIndex parameter either represents the instance index or gl_InstanceID (always defined for Vulkan, if the machine has the GL_ARB_shader_draw_parameters extension for OpenGL).
Finally, most vanilla shaders require the machine to have the GL_ARB_separate_shader_objects extension as a requirement of Vulkan, failing if not present. This is functionally the same as requiring a higher GLSL version.
// In some shader file.
// Required extensions for the shader.
#extension GL_ARB_separate_shader_objects : require
// Includes for functions.
#include <minecraft:light.glsl>
#include <minecraft:fog.glsl>
#include <minecraft:dynamictransforms.glsl>
#include <minecraft:projection.glsl>
#include <minecraft:sample_lightmap.glsl>
// Layout followed by the location.
layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;
layout(location = 2) in vec2 UV0;
layout(location = 3) in ivec2 UV1;
layout(location = 4) in ivec2 UV2;
// The location specified by the out uniforms in
// the vertex shader must match the `in`s in the
// fragment shader.
// Since it matches by location now, the variable names
// are ignored, but it is recommended to keep them consistent.
layout(location = 0) out float sphericalVertexDistance;
layout(location = 1) out float cylindricalVertexDistance;
Order Independent Transparency (OIT)
Minecraft now supports the use of Order-Independent Transparency (OIT) through its improved transparency option. As the name implies, OIT is a rendering technique that tries to resolve alpha compositing without the underlying geometry having to be manually sorted by depth. Vanilla specifically uses Wavelet OIT, which is a topic too complicated for a Minecraft primer. If you're interested, I suggest reading up on the topic yourself.
For our understanding, OIT runs through three stages: depth bounds, transmittance, and accumulate. In both depth bounds and transmittance, only the alpha is updated. It is only during the accumulate phase that the pixel color is set. As such, OIT requires updating both the vertex and the fragment shader. For both depth bounds and transmittance, alpha only OIT is denoted by the shader define OIT_ALPHA_ONLY, which you will see scattered across the supported shaders.
Note that the following is the common usecase in vanilla's shaders. What you actually do will depend on your own.
In the vertex shader, OIT_ALPHA_ONLY is commonly checked to prevent the fog, lightmap, or overlay color as they do not contribute to the alpha passes:
// In some .vsh file.
// In `assets/examplemod/shaders/core/example_oit_supported.vsh`
#version 330
#extension GL_ARB_separate_shader_objects : require
#include <minecraft:fog.glsl>
#include <minecraft:dynamictransforms.glsl>
#include <minecraft:projection.glsl>
#include <minecraft:sample_lightmap.glsl>
// Some passed in uniforms.
// We'll say UV0 is for our texture.
// UV2 is the lightmap.
layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;
layout(location = 2) in vec2 UV0;
layout(location = 3) in ivec2 UV2;
// The uniforms to pass to the fragment shader.
// If the flag is not defined, include the fog distance.
// Otherwise, it is not necessary for the alpha pass.
#ifndef OIT_ALPHA_ONLY
layout(location = 0) out float sphericalVertexDistance;
layout(location = 1) out float cylindricalVertexDistance;
#endif
layout(location = 2) out vec4 vertexColor;
layout(location = 3) out vec2 texCoord0;
// If the flag is not defined, include the lightmap.
// Otherwise, it is not necessary for the alpha pass.
#ifndef OIT_ALPHA_ONLY
uniform sampler2D Sampler2;
#endif
// Basic main function.
void main() {
vec3 pos = Position + ModelOffset;
gl_Position = ProjMat * ModelViewMat * vec4(pos, 1.0);
// If the flag is not defined, set the color multiplied
// by the lightmap; otherwise, just leave the color for
// the alpha pass.
#ifndef OIT_ALPHA_ONLY
sphericalVertexDistance = fog_spherical_distance(Position);
cylindricalVertexDistance = fog_cylindrical_distance(Position);
vertexColor = Color * sample_lightmap(Sampler2, UV2);
#else
vertexColor = Color;
#endif
texCoord0 = UV0;
}
In the fragment shader, it must include minecraft:oit.glsl, making sure to handle the correct inputs based on OIT_ALPHA_ONLY. During the depth bounds and transmittance phase, the fragment color is not set as part of the alpha phase, and instead executeAlphaOnlyPhase is called. Then, during accumulate, the fragment color is determined from the texture color passed into sampleColorForAccumulation.
// In some .fsh file.
// In `assets/examplemod/shaders/core/example_oit_supported.fsh`
#version 330
#extension GL_ARB_separate_shader_objects : require
#include <minecraft:fog.glsl>
#include <minecraft:dynamictransforms.glsl>
#include <minecraft:oit.glsl>
// The passed in uniforms.
uniform sampler2D Sampler0;
// Matching the flag based on the vertex shader outputs
// for the same reasons.
#ifndef OIT_ALPHA_ONLY
layout(location = 0) in float sphericalVertexDistance;
layout(location = 1) in float cylindricalVertexDistance;
#endif
layout(location = 2) in vec4 vertexColor;
layout(location = 3) in vec2 texCoord0;
// The output uniforms.
// If the flag is not defined, include the fragment color.
// Otherwise, it is not necessary for the alpha pass.
#ifndef OIT_ALPHA_ONLY
layout(location = 0) out vec4 fragColor;
#endif
// Calculate the final fragment color.
vec4 calculateFinalColor(vec4 color) {
// If in the accumulate phase, sample the OIT calculated color.
#ifdef OIT_ACCUMULATE
color = sampleColorForAccumulation(color);
vec4 fogColor = vec4(FogColor.rgb * color.a, FogColor.a);
#else
vec4 fogColor = FogColor;
#endif
// Compute the fragment color.
return apply_fog(color, sphericalVertexDistance, cylindricalVertexDistance, FogEnvironmentalStart, FogEnvironmentalEnd, FogRenderDistanceStart, FogRenderDistanceEnd, fogColor);
}
void main() {
vec4 color = texture(Sampler0, texCoord0) * vertexColor * ColorModulator;
// If in an alpha only phase, update the OIT values.
#ifdef OIT_ALPHA_ONLY
executeAlphaOnlyPhase(gl_FragCoord.z, color.a);
#else
// Otherwise, set the fragment color.
fragColor = calculateFinalColor(color);
#endif
}
These shaders can then be used like any other RenderPipeline:
public static final RenderPipeline.Snippet GENERIC_EXAMPLE_SNIPPET = RenderPipeline.builder()
// Setting up all the layouts and transforms used.
.withBindGroupLayout(BindGroupLayouts.GLOBALS)
.withBindGroupLayout(BindGroupLayouts.FOG)
.withBindGroupLayout(BindGroupLayouts.SAMPLER0)
.withVertexBinding(0, DefaultVertexFormat.BLOCK)
.withPrimitiveTopology(PrimitiveTopology.QUADS)
.withDepthStencilState(DepthStencilState.DEFAULT)
.withBindGroupLayout(BindGroupLayouts.DYNAMIC_TRANSFORMS)
// Specify our vertex shaders and the like.
.withVertexShader(Identifier.withNamespaceAndPath("examplemod", "core/example_oit_supported"))
.withFragmentShader(Identifier.withNamespaceAndPath("examplemod", "core/example_oit_supported"))
.buildSnippet();
public static final RenderPipeline.Snippet EXAMPLE_OIT_SUPPORTED_SNIPPET = RenderPipeline.builder(GENERIC_EXAMPLE_SNIPPET)
// Setting up all the layouts and transforms used.
.withBindGroupLayout(BindGroupLayouts.SAMPLER2)
.withBindGroupLayout(BindGroupLayouts.PROJECTION)
.buildSnippet();
public static final RenderPipeline CLASSIC_EXAMPLE_OIT_SUPPORTED = RenderPipeline.builder(EXAMPLE_OIT_SUPPORTED_SNIPPET)
.withLocation(Identifier.withNamespaceAndPath("examplemod", "pipeline/example_oit_supported"))
.withColorTargetState(new ColorTargetState(BlendFunction.TRANSLUCENT))
.withDepthStencilState(DepthStencilState.DEFAULT)
.build();
The pipeline on its own cannot make use of OIT, however. For that, we need to create an OitPipelineSet, created through builder. At its core, the builder constructs three RenderPipelines corresponding to each of the three phases. It takes in a base snippet that will be accessible to all three phases, but if one pipeline requires additional uniforms or layouts, it can be specified using with*Modifier. Finally, the OIT pipeline is built using build:
public static final OitPipelineSet EXAMPLE_OIT_SUPPORTED = OitPipelineSet.builder(
// A suffix for naming the pipeline.
"example_oit_supported",
// The basic builder for the three phases.
// Note that we pass in a snippet containing all of the
// non-phase isolated shader code.
RenderPipeline.builder(GENERIC_EXAMPLE_SNIPPET)
)
// If we need to modify the pipeline, we can call:
// - withDepthBoundsModifier
// - withTransmittanceModifier
// - withAccumulateModifier
// In our case, our shader makes use of Sampler2 for the final color,
// so it should be provided during the final phase (i.e., accumulate).
.withAccumulateModifier(accumulate -> accumulate.withBindGroupLayout(BindGroupLayouts.SAMPLER2))
.build();
Then, within our RenderType, we can specify the OIT pipeline to use by calling RenderSetup#setOitPipelines:
public static RenderType oitSupported(Identifier texture) {
// Set the classic pipeline without OIT support.
RenderSetup state = RenderSetup.builder(CLASSIC_EXAMPLE_OIT_SUPPORTED)
// Set the OIT pipelines.
.setOitPipelines(EXAMPLE_OIT_SUPPORTED)
.withTexture("Sampler0", texture)
.useLightmap()
.sortOnUpload()
.createRenderSetup();
return RenderType.create("examplemod:oit_supported", state);
}
With all that, we can then make use of the OIT pipeline by calling RenderType#prepare and finally PreparedRenderType#drawFromBufferOit within a RenderPass, setting all the required uniforms.
Feature Phase Changes
The render phases used by the FeatureRenderDispatcher have been partially reorganized due to some renames.
SubmitNodeCollection#seeThroughNameTags is now called seeThrough to hold both name tags and text with fonts having DisplayMode#SEE_THROUGH. Additionally, nameTag only contains the translucent portion, with anything solid being sent to solid. gizmos was renamed to translucentGizmos, while alwaysOnTop was renamed to alwaysOnTopGizmos. Solid gizmos were also merged into solid.
Additionally, if improved transparency (OIT) is enabled, then seeThrough, shadows, nameTags, texts, shapeOutlines, translucentBlocksAndItems, translucentModels, translucentCustomGeometry, breakingOverlay, afterTerrain, and translucentGizmos all use oitTranslucent. This means that if you have a SubmitNodeStorage opted into OIT via setUseImprovedTransparency, you cannot use FeatureRenderDispatcher#renderAllFeatures as it will render the same phase elements multiple times.
Palette Metadata
A new metadata section has been added to the PNG mcmeta for marking a texture as paletted, replacing the armor trims atlas. The section is denoted by a palette key, specifying the base_palette of the corresponding texture relative to textures/palettes.
Textures making use of the palette section are handled through PalettedTextureManager, which dynamically constructs a texture containing the permutations for all palettes defined relative to textures/palettes. Note that this is only used for entity textures. Item textures still remain the same.
// For some PNG texture
// In assets/examplemod/textures/trims/example_trim.png.mcmeta
{
// The palette metadata section
"palette" : {
// Points to `assets/minecraft/textures/palettes/trim_base.png`
"base_palette" : "minecraft:trim_base"
}
}
To actually make use of the paletted texture, it can be requested through PalettedTextureManager#getOrPrepare, passing in the base texture id along with the palette texture id. The identifier to the associated texture can then be obtained through the returned PalettedTextureManager$Handle#textureLocation, like EquipmentLayerRenderer does.
The metadata section also changes how trim materials are defined and overridden. Now the TrimMaterial takes in a palette_id instead of an asset_name, pointing directly to the associated palette to use. The overrides are then specified on the EquipmentClientInfo through trim_overrides. Each override defines a EquipmentClientInfo$TrimPredicate indicating for what material and pattern the override should match, and the replacement texture and palette identifiers to use instead of the ones specified by the material and pattern.
// For some equipment assets.
// In assets/examplemod/equipment/example.json
{
// ...
"trim_overrides": [
{
"when": {
// When the trim material is diamond.
"material": "minecraft:diamond",
// And when the pattern is coast.
"pattern": "minecraft:coast"
},
// Use the overridden palette instead of the
// one specified by the trim material.
// Points to `assets/minecraft/textures/palettes/trim/diamond_darker.png`
"palette": "minecraft:trim/diamond_darker",
// Use the overridden texture.
// How it resolves depends on use case.
// In `EquipmentLayerRenderer`, it overrides the
// trim pattern asset.
// Points to `assets/minecraft/textures/trims/entity/<layer>/snout.png`
"texture": "minecraft:snout"
}
]
}
Item Quads
Items now handle submitting their quads through ItemQuads. This functionally is a wrapper around a list of BakedQuads, separating the quads into whether they are solid and translucent in response to the feature phase changes. ItemQuads#solid are submitted to the general SubmitNodeCollection#solid phase, ItemQuads#translucent are submitted to SubmitNodeCollection#translucentBlocksAndItems, and if the item has an outline, ItemQuads#all are submitted to SubmitNodeCollection#outline.
Creating an ItemQuads from a list of BakedQuads can be easily done by calling ItemQuads#split:
// For some List<BakedQuad> quads
ItemQuads itemQuads = ItemQuads.split(quads);
// For some QuadCollection collection
ItemQuads itemQuads = ItemQuads.split(collection.getAll());
Given that the quads could be called every frame, the ItemQuads should be stored in their used location whenever possible:
// An example `ItemModel` implementation
public class ExampleItemModel implements ItemModel {
private final ItemQuads itemQuads;
private ExampleItemModel(QuadCollection collection) {
// Store the item quads
this.itemQuads = ItemQuads.split(collection.getAll());
// ...
}
@Override
public void update(ItemStackRenderState output, ItemStack item, ItemModelResolver resolver, ItemDisplayContext displayContext, @Nullable ClientLevel level, @Nullable ItemOwner owner, int seed) {
output.appendModelIdentityElement(this);
ItemStackRenderState.LayerRenderState layer = output.newLayer();
// ...
// Set the quads on the layer
layer.setQuads(this.itemQuads);
// ...
}
// ...
}
Submitting Crumbling Overlays
The ModelFeatureRenderer$CrumblingOverlay applied to entity models (e.g., banners, chests, etc.) are now passed to OrderedSubmitNodeCollector#submitCrumblingOverlay for rendering. As such, submitModel and submitModelPart no longer take in the crumbling overlay.
OrderedSubmitNodeCollector#submitCrumblingOverlay takes in the same fields as submitModel and submitModelPart aside from the TextureAtlasSprite and the outline color:
// For some `OrderedSubmitNodeCollector` collector
collector.submitCrumblingOverlay(
// The entity model to render.
model,
// The render state extracted from the associated entity.
state,
// The pose stack.
poseStack,
// The render type. This should be what was used to render
// the actual entity model.
renderType,
// The light coordinates. This should normally be obtained
// from the submission context.
LightCoordsUtil.FULL_BRIGHT,
// The overlay coordinates. This should normally be obtained
// from the submission context.
OverlayTexture.NO_OVERLAY,
// The tint color to apply to the texture.
-1,
// The crumbling overlay of how much progress has been made.
crumblingOverlay
);
Like before, the passed in RenderType is only used to check whether it RenderType#affectsCrumbling, which must be true for the overlay to be submitted; and if the RenderType#hasBlending, which submits to the SubmitNodeCollection#breakingOverlay phase if true, and the SubmitNodeCollection#solid phase if false. The actual RenderType submitted is pulled from ModelBakery#DESTROY_TYPES (or DESTROY_TYPES_OIT if improved transparency is enabled) using the progress display.
assets/minecraft/atlases/armor_trims.jsonis removedassets/minecraft/models/block/template_farmland.json->template_cube_bottom_top_indented.json, not one-to-oneassets/minecraft/models/item/light.jsonis removedassets/minecraft/post_effect/transparency.jsonis removedassets/minecraft/shaders/coreblit_depth.fsh- A fragment shader that sets the depth based on the red channel of the sampled texture.integrate_depth.fsh- A fragment shader that sets the depth based on the red channel of the sampled texture, discarding if the depth is 0.oit_composite.fsh- An order-independent transparency fragment shader that composites a sampler with its depth bounds.oit_depth_bounds_cull.fsh- An order-independent transparency fragment shader that sets the depth from its bounds.rendertype_clouds->cloudsrendertype_world_border->world_bordertext_backgroundis removed- Merged into
text
- Merged into
assets/minecraft/shaders/includeoit*.glsl- Utilities for order-independent transparency shaders.terrainglobals.glsl- The UBO definition for the terrain uniform.texture_sampling.glsl- Utility for texture sampling.
assets/minecraft/shaders/post/transparency.jsonis removedcom.mojang.blaze3dGLFWErrorCaptureclass is removedGLFWErrorScopeclass is removedGpuDeviceLossException->renderpearl.api.device.GpuDeviceLossExceptionGpuFormat->renderpearl.api.GpuFormatGpuOutOfMemoryException->renderpearl.api.device.GpuOutOfMemoryExceptionIndexType->renderpearl.api.pipeline.IndexTypePrimitiveTopology->renderpearl.api.pipeline.PrimitiveTopology
com.mojang.blaze3d.buffersGpuBuffer->renderpearl.api.buffers.GpuBuffer, now an interface from a class- The class portion has been moved into
renderpearl.backend.common.BaseGpuBuffer
- The class portion has been moved into
GpuBufferSlice->renderpearl.api.buffers.GpuBufferSliceGpuFence->renderpearl.api.commands.GpuFenceNO_TIMEOUT- A constant that represents that awaiting the fence completion should not timeout with an exception.
com.mojang.blaze3d.opengl.*->renderpearl.backend.opengl.*FrameBufferCachegetFbonow has an overload that takes in the mipmap offsetint$CacheKeynow takes in a mipmap offsetint
GlCommandEncoder#executeDrawMultipleis removed- The frontend now just calls
executeDrawmultiple times
- The frontend now just calls
GlDevicenow takes in theGlBackendinstead of thelongwindow handle and defaultShaderSourceheuristics- Returns the OpenGl device heuristics.getOrCompilePipeline,getOrCompileShaderare removed- Handled by the
GlPipelineRecompiler
- Handled by the
precompilePipeline->GpuDeviceBackend#compilePipeline, not one-to-onevertexArrayCacheis removed
GlHeuristics#isNvidia,couldBeIntelGen7- Checks for specific graphics card types.GlProgramBUILT_IN_UNIFORMS,INVALID_PROGRAMare removedlinknow takes in a list ofGlShaderModulesinstead of the specific vertex and fragment shader along with theVertexFormatbindingssetupBindGroupLayoutsnow takes in a list ofBindGroupLayout$UniformDescriptionsinstead of the rawBindGroupLayoutsgetUniformnow takes in anintindex instead of theStringnameuniformCount- Returns the number of uniforms used by the program.getUniformsis removedpushConstant- Returns the UBO uniform emulating the push constant.
GlRenderPassno longer takes in abooleanfor whether there is a depth textureindexBufferDirty- Whether the index buffer has been bound since the last draw.scissorStateDirty- Whether the scissor state has changed since the last draw.dirtyUniforms,anyUniformDirty- Handles the marking of new data in uniforms.pushConstants,pushConstantsDirty- Push constants defined in the pass.
GlRenderPipelineis now a final class instead of a record- The constructor is now package-private from
public program- The program used by the pipeline.vertexArray- The vertex attributes used by the pipeline.bind- Binds the pipeline for use.primitiveTopology- The topology used by the pipeline.
- The constructor is now package-private from
GlShaderModulegetId,getDebugLabelreplaced bygetLabelgetType- Returns the type of the shader.
GlStateManager#_glReadBuffer- Reads the buffer using the given color buffer.GlSurfaceconstructor is now package-private frompublicUniform$Utbno longer takes in theintlocationVertexArrayCache->VertexArray, now sealed to$Emulated,$Seperate; not one-to-one- The array objects are now owned by a given
GlRenderPipelineinstead of being globally cached createreplaced bycreateSource, providing the lambda to construct the array instead of the array itselfbindVertexArrayreplaced bybind, only taking in theGpuBufferSlicevertex buffers$Emulated,$Separateconstructors are nowprivateinstead ofpublic
- The array objects are now owned by a given
com.mojang.blaze3d.pipelineBindGroupLayout->renderpearl.api.pipeline.BindGroupLayoutgetSamplers,getUniformsare removedflattenSamplersis removed$Builder#withSampleris removed
BlendEquation->renderpearl.api.pipeline.BlendEquationBlendFunction->renderpearl.api.pipeline.BlendFunctionMAX- Blends the source and destination by selecting the pixel with the maximum value.
CompiledRenderPipeline->renderpearl.api.pipeline.CompiledRenderPipelineisValidis removedisClosed- Checks whether the pipeline has been closed.$Pending- A pipeline representation that hasn't been fully compiled yet.
DepthStencilState->renderpearl.api.pipeline.DepthStencilStatePipelineCache- A class for caching the compiled pipelines.RenderPipeline->renderpearl.api.pipeline.RenderPipeline- The constructor now takes in a map of
ShaderTypeto ids instead of specifying theIdentifierfor each shader type directly, and theintsize of the push constant getColorTargetStateis removedgetVertexShader,getFragmentShadermerged ingetShaderspushConstantSize- Returns the size of the push constant.$Snippetnow takes in a map ofShaderTypeto ids instead of specifying theIdentifierfor each shader type directly, and theintsize of the push constant
- The constructor now takes in a map of
RenderTargetnow takes in a nullableGpuFormatfor the depth instead of just abooleanto determine whether to use depthuseDepthreplaced bydepthFormat- The original
booleancan be queried viahasDepth
- The original
format->colorFormatcopyColorFrom- Copies the color texture from anotherRenderTarget.
TextureTargetnow takes in a nullableGpuFormatfor the depth instead of just abooleanto determine whether to use depth
com.mojang.blaze3d.platformBlendFactor->renderpearl.api.pipeline.BlendFactorBlendOp->renderpearl.api.pipeline.BlendOpClipboardManagerFORMAT_UNAVAILABLEis removedgetClipboardno longer has any argumentssetClipboardno longer takes in theWindow
CompareOp->renderpearl.api.pipeline.CompareOpGLXis removed, replaced bySdlDebugandSDLEventHandlerIconSetgetStandardIcons,getFilenow take inPackMetadataResourcesinstead ofPackResourcesgetMacIconis removed
InputConstantshave been remapped for SDLCURSOR*are removedKEYCODE_*- The logical codes for the given key.isKeyDownno longer takes in theWindowsetupKeyboardCallbacks,setupMouseCallbacksare removedgrabOrReleaseMousesplit intograbMouse,releaseMouseisRawMouseInputSupported,updateRawMouseInputare removed$TypeKEYSYM->KEYBOARDSCANCODEis removed
MacosUtilis nowfinal, with its constructor madeprivateexitNativeFullscreen,clearResizableBit,loadIcon,setWindowColorSpaceForOpenGLBecauseGLFWDoesntare removeddisableCloseWindowMenuItem- Disables the close window menu.setFullscreenMenuVisibility- Toggles the fullscreen menu visibility.setCtrlClickEmulatesRightClick- Toggles whether control emulates right click.
MessageBoxconstants are eitherprivateor removedMonitornow takes in anintid instead of alonghandleMonitorManageris no longerAutoCloseablegetMonitornow takes in anintid instead of alonghandleclampis removedonDisplayConnected,onDisplayDisconnected,onDisplayModeChanged- Handles a display's state.
NativeImageread(NativeImage$Format, InputStream),read(NativeImage$Format, ByteBuffer)are removed$Format#supportedByStbis removed
NativeLibrariesBootstrap#loadGlfwreplaced byloadSdlPolygonMode->renderpearl.api.pipeline.PolygonModeSdlDebug- A class for handling SDL debug logging.SDLEventHandler- An event handler for SDL.TextInputManagernotifyIMEChangedis removedtickis removedstartTextInputnow takes in anObjectownerstopTextInputnow has an overload that takes in anObjectowneronTextInputFocusChangenow takes in anObjectowner
VideoModenow takes in aSDL_DisplayModeinstead of aBufferorGLFWVidModeCODEC- The codec forVideoMode.getRefreshRatenow returns afloatinstead of anintrefreshRateLabel- A formatted refresh rate.
Windowno longer throws aBackendCreationException, and now takes in anintfor the maximum size of the windowMIN_WINDOW_WIDTH,MIN_WINDOW_HEIGHT- The minimum bounds of the game window.createGlfwWindowreplaced bycreateWindow, now privatecreateIconSurface- Creates the surface for the given icon image.getActiveVideoMode- Returns the active video mode on the current display.getActiveDisplayMode- Returns the active display mode.getRefreshRateis removedcheckGlfwErroris removedhandleEvent- Handles events sent from SDL.setIconnow takes inPackMetadataResourcesinstead ofPackResourcesgetErrorSection- Returns the error sent by the window.defaultErrorCallbackis removedqueryFramebufferSize- Gets the size of the main framebuffer from the given window.toggleFullScreenreplaced bysetFullscreen,setExclusiveFullscreen, taking in thebooleanfor fullscreen modeisExclusiveFullscreen- Whether the window is in exclusive fullscreen mode.isFullscreenis removedsetWindowMaxSize- Sets the window maximum size.updateRawMouseInputis removedisMinimizedis removedgetPixelDensity- Returns the pixel density in the current windowsetQuitShortcuts- Sets whether windows should close on alt + f4.backendis removed$FramebufferSize- The size of the current window framebuffer.
WindowEventHandler#fullscreenStateChanged- Handles when the game changes its fullscreen state.
com.mojang.blaze3d.platform.cursor.CursorType#selectno longer takes in aWindowcom.mojang.blaze3d.preprocessor.GlslPreprocessorclass is removedcom.mojang.blaze3d.resource.RenderTargetDescriptornow takes in$TexturePropertiesfor the color and depth instead of the depthboolean,Vector4fcclear color, andGpuFormat$TextureProperties- The properties for a given texture.
com.mojang.blaze3d.shadersGpuDebugOptions->renderpearl.api.device.GpuDebugOptionsShaderSource->renderpearl.api.pipeline.ShaderSource, now implementsAutoCloseableget->getShadergetInclude- Returns the cached included shader.$CachedIncludeSource- A reference to the cached include source.
ShaderType->renderpearl.api.pipeline.ShaderTypeUniformType->renderpearl.api.pipeline.UniformType
com.mojang.blaze3d.systemsBackendCreationException->renderpearl.api.device.BackendCreationExceptionCommandEncoder->renderpearl.frontend.FrontendCommandEncoder- Definition interface in
renderpearl.api.commands.CommandEncoder
- Definition interface in
CommandEncoderBackend->renderpearl.backend.api.CommandEncoderBackendDeviceFeatures->renderpearl.api.device.DeviceFeatureswireframeFillMode- IfPolygonMode#WIREFRAMEcan be used to render the model.
DeviceInfo->renderpearl.api.device.DeviceInfoDeviceLimits->renderpearl.api.device.DeviceLimitsmaxDrawIndirectDrawCount- The maximum number of indirect draws that can be made perdrawIndirectcall.
DeviceType->renderpearl.api.device.DeviceTypeGpuBackend->renderpearl.api.device.GpuBackendsetWindowHints,handleWindowCreationErrorsare removedloadLibrary,unloadLibrary- Handles the native libraries required for the backend to run.createWindow- Creates the window for the application.createDevicenow only takes in theGpuDebugOptions
GpuDevice->renderpearl.frontend.FrontendGpuDevice, no longer taking in theRunnablefor the critical shader loader- Definition interface in
renderpearl.api.device.GpuDevice STRICT_VALIDATION- Whether the GPU calls should be strictly validated.createSurfacenow takes in aBooleanSupplierfor if the game is minimizedprecompilePipelinereplaced bycompilePipelineclearPipelineCacheis removedloadCriticalShadersis removedgetTimestampNowis removed
- Definition interface in
GpuDeviceBackend->renderpearl.backend.api.GpuDeviceBackendcreateSurfacenow takes in aBooleanSupplierfor if the game is minimizedprecompilePipelinereplaced bycompilePipelineclearPipelineCacheis removedgetTimestampNowis removedgetTimestampCalibrationOffset- Returns the nanosecond offset between the current host time and the device time.
GpuQuery->renderpearl.api.commands.GpuQuerynow implementsUncheckedAutoCloseableGpuQueryPool->renderpearl.api.commands.GpuQueryPoolnow implementsUncheckedAutoCloseableGpuSurface->renderpearl.frontend.FrontendGpuSurface- Definition interface in
renderpearl.api.device.GpuSurface $Configuration->GpuSurface$Configuration$PresentMode->GpuSurface$PresentMode
- Definition interface in
GpuSurfaceBackend->renderpearl.backend.api.GpuSurfaceBackendHintsAndWorkarounds->renderpearl.api.device.HintsAndWorkaroundsisExplicitDepthRequired- If the depth of the fragment coordinate must be explicitly specified.multiDrawIndirectHasKnownIssues- If indirect multidraw has issues when calling.
RenderPass->renderpearl.frontend.FrontendRenderPass- Definition interface in
renderpearl.api.commands.RenderPass - The class now implements
RenderPass$UniformUploader indexBuffer- The current index buffer.uniforms- The current uniforms.setPipelinenow takes in aCompiledRenderPipelineinstead of theRenderPipelinebindTextureis removedpushConstants- Pushes constants to the buffer.$Draw->RenderPass$Draw$RenderArea->RenderPass$RenderArea$UniformUploader->RenderPass$UniformUploaderupload->setUniformpushConstants- Pushes constants to the buffer.
- Definition interface in
RenderPassBackend->renderpearl.backend.api.RenderPassBackendsetUniformmerged into one call with anObjectvaluedrawMultipleIndexedmoved toRenderPass#drawMultipleIndexed
RenderPassDescriptor->renderpearl.api.commands.RenderPassDescriptor, now a record- The original descriptor is now in
RenderPassDescriptor$Builder create->builder, not one-to-one$Builder#build- Builds the pass descriptor.
- The original descriptor is now in
RenderSystemoutputColorTextureOverride,outputDepthTextureOverrideare removedisRenderingLevel- Whether the level is currently being rendered.setFallbackPipelineCache,setCurrentPipelineCache- Handles setting the pipeline cache.getCompiledPipelineNullable,getCompiledPipeline- Gets the compiled pipeline.pollEventsnow takes in anSDLEventHandlerpumpEvents- Flushes and repolls the SDL events.setErrorCallbackis removedtrackBackendLibraryForShutdown,unloadTrackedBackendLibrary- Handles tracking theGpuBackend.isWireframeAvailable- Whether the models can be rendered as wireframes.getDynamicUniformsnow returnsDynamicGpuDatainstead ofDynamicUniformsresizeAllAutoStorageIndexBuffers- Resizes the auto storage index buffers.$AutoStorageIndexBufferrequestIndexCount- Sets the index count.resizeToRequestedIndexCount- Ensures the buffer as the requested index count.getBuffer- Gets the backingGpuBuffer.
SurfaceException->renderpearl.api.device.SurfaceExceptionTracyGpuProfiler->renderpearl.frontend.TracyGpuProfiler- The constructor now takes in a
FrontendGpuDeviceinstead of aGpuDevice
- The constructor now takes in a
com.mojang.blaze3d.textures.*->renderpearl.api.textures.*GpuSampleris now an interface instead of an abstract classisClosed- Whether the sampler has been closed.
GpuTextureis now an interface from a class- The class portion has been moved into
renderpearl.backend.common.BaseGpuTexture isClosed- Whether the texture has been closed.
- The class portion has been moved into
GpuTextureViewis now an interface from a class- The class portion has been moved into
renderpearl.backend.common.BaseGpuTextureView isClosed- Whether the texture view has been closed.
- The class portion has been moved into
com.mojang.blaze3d.util.TransientBlockAllocator->renderpearl.backend.util.TransientBlockAllocator- The generic now extends
$Allocator$Block $Allocatorgeneric now extends$Allocator$Block$Block- A representation of a 'block' of data.$CpuBlock- A block on the CPU.
- The generic now extends
com.mojang.blaze3d.vertexDefaultVertexFormatUV3_SEMANTIC_NAME- The name for UV3.CHUNK_POSITION_SEMANTIC_NAME,CHUNK_VISIBILITY_SEMANTIC_NAME- Names for chunk settings.CHUNK_DATA_INSTANCED- The format for chunk data.ENTITY_GLINT_SPECIAL- The format for special entity glints.
PoseStackmulPose->rotate- Now has an overload that takes in an
Axisand the radian angle
- Now has an overload that takes in an
rotateDegrees- Rotates around theAxisin degrees.$Poserotatenow has an overload that takes in anAxisand the radian anglerotateDegrees- Rotates around theAxisin degrees.
SheetedDecalTextureGenerator#setSheetedDecalUv- Sets the UV coords for the decal.
VertexConsumersetUv3- Sets the UV coords for the sheeted decal.putBakedQuadWithGlint- Puts the baked quad data that has a glint.
VertexFormat->renderpearl.api.vertex.VertexFormatVertexFormatElement->renderpearl.api.vertex.VertexFormatElement
com.mojang.blaze3d.vulkan.*->renderpearl.backend.vulkan.*VulkanBackend- Constants moved to
VulkanFeatureSetsREQUIRED_DEVICE_EXTENSIONS,REQUIRED_DEVICE_FEATURESmerged intoVulkanFeatureSets#REQUIRED_FEATURESET
- Constants moved to
VulkanBindGroupLayoutrecord is removedVulkanConst#toVknow has an overload that takes in theShaderTypeVulkanDeviceno longer takes in theShaderSourceVulkanGpuTextureViewnow extendsBaseGpuTextureViewinstead ofGpuTextureViewVulkanRenderPass#VALIDATION->FrontendGpuDevice#STRICT_VALIDATIONuniformsis now aReferenceListinstead of aHashMaptexturesis removed$TextureViewAndSampler->renderpearl.util.TextureViewAndSampler
VulkanRenderPipelineis now a final class instead of a record- The constructor no longer takes in a
RenderPipelineand takes in aLongListshader modules instead oflongmodules for the vertex and fragment, thelongdescriptor set, and a list ofBindGroupLayout$UniformDescriptions instead of theVulkanBindGroupLayout compilenow takes in theBackendRenderPipeline$CreateInfoinstead of theVulkanBindGroupLayout,RenderPipeline, andlongmodulesdevice- The gpu device of the pipeline.withDepthPipeline,withoutDepthPipeline- The specific pipelines given the depth.pipelineLayout- The layout for the pipeline, references aVkPipelineLayout.uniforms- The uniforms used by the pipeline.
- The constructor no longer takes in a
VulkanUtilsenumerateExtensions- Returns all available extensions for the device.enumerateFeatures- Returns all available features for the device.
com.mojang.blaze3d.vulkan.checkpoints.*->renderpearl.backend.vulkan.checkpoints.*com.mojang.blaze3d.vulkan.glslGlslCompiler->renderpearl.frontend.shaders.GlslCompiler- The constructor now takes in the
booleans for zero to one, and draw parameters createIntermediaryis removedcompilereplaced bycompileSpv$CompiledModulesis removed
- The constructor now takes in the
IntermediaryShaderModulerecord is removed- This is technically replaced in usage by
SpvModule, but it is completely different
- This is technically replaced in usage by
ShaderCompileException->renderpearl.util.ShaderCompileExceptionSpvcUtilclass is removedSpvSamplerrecord is removedSpvUniformBufferrecord is removedSpvVariablerecord is removed
com.mojang.blaze3d.vulkan.init.*->renderpearl.backend.vulkan.init.*VulkanPNextStructnow takes in the next structClass- There is also an overload that only takes the
Class
- There is also an overload that only takes the
fieldOffset- Returns the offset of the given field name.
com.mojang.renderpearl.backend.api.SpvModule- An intermediate module representing the compiled shader in SPV.com.mojang.renderpearl.backend.opengl.GlPipelineRecompiler- Handles recompiling the SPV shader module into GLSL.com.mojang.renderpearl.backend.vulkan.VulkanFeatureSets- The feature sets for vulkan used by vanilla.com.mojang.renderpearl.frontend.shadersPipelineBuilder- The compiler for pipelines and their associated shaders.SPIRVModule- An intermediate shader module implementation in the SPIR-V format.SpvUtil- A utility for working with SPVs.
com.mojang.renderpearl.util.UncheckedAutoCloseable- AnAutoCloseablethat removes theExceptionthrows fromclose.net.minecraft.clientCamera#extractRenderStatenow takes in theDeltaTrackerinstead of thefloatpartial tickClientClockManagergetInstanceis nowpublicfromprivate, returning a$ClientClockInstance$ClockInstance->$ClientClockInstance, nowpublicfromprivate, implementingClockInstance
KeyboardManagerkeyPressis nowpublicfromprivatecharTypedis nowpublicfromprivatetextInput,textEditing- Handles input into a text box, including preedit.setupis removed
MinecraftmultiDrawIndirect- Whether the terrain should make use of indirect multidraw calls.getPalettedTextureManager- Gets the texture manager for palletted permutations.
MouseHandleronButtonis nowpublicfromprivateonScrollis nowpublicfromprivateonDropis nowpublicfromprivate, taking in a list ofStringpaths instead ofPaths and theintnumber of failed filessetupis removedonMoveis nowpublicfromprivate, taking in the relativedoublex and y positionresyncMousePosition- Resyncs the mouse position.
OptionsDEBUG_GUI_SCALE_UNCHANGED- A constant represent that the debug GUI scaling should remain unchanged.rawMouseInputis removedquitShortcuts- Whether quit shortcuts (alt + f4) can be used.ctrlClickEmulatesRightClick- Whether control emulates right click.macFullscreenMenuVisibility- Whether the fullscreen menu visibility on Macs.debugGuiScale- The GUI scaling for the debug items.
net.minecraft.client.color.itemItemTintSourcesminecraft:map_coloris removedMapColorrecord is removed
net.minecraft.client.data.modelsBlockModelGeneratorscreateFlatItemModelWithBlockTextureAndOverlay->createTwoLayeredItemModel, not one-to-onecreateFlatItemModel- Creates a flat item with the given material.registerTwoLayerFlatItemModelis removedcreateRotatedVariantBlocknow has an overload to specify the model either via aTexturedModel$ProviderorIdentifiercreateStrawBed- Creates a straw bed.createFarmlandnow takes in the farmlandBlock, the base and bottomMaterials, and theModelTemplatecreateDirtPathis removedcreateShelfMushroom- Creates a shelf mushroom.$BlockFamilyProvider#carpet- Adds the carpet model for a block family.$PlantType#createItemModelreplaced bycreateItemModelUsingBlockTexture
EquipmentAssetProvider#onlyHumanoid,humanoidAndMountArmornow return a$Builderinstead of theEquipmentClientInfoitselfItemModelGeneratorsprefixForSlotTrimis nowprivatefrompublicgenerateFlatItemnow as an overload that takes in theIdentifierfor the texture instead of anItemgenerateTrimmableItemnow takes in a map ofTrimMaterials$PalettetoTrimMaterials$Paletteinstead of aResourceKey<EquipmentAsset>generateTrimmableArmorSet- Generates a trimmable item model for each piece of armor.$TrimMaterialData#assets->palette, now aTrimMaterials$Paletteinstead of aMaterialAssetGroup
net.minecraft.client.data.models.modelModelTemplates#FARMLANDreplaced byCUBE_BOTTOM_TOP_INDENTEDTexturedModelCUBE_TOP_BOTTOM->CUBE_BOTTOM_TOPCUBE_BOTTOM_TOP_INDENTED- A model provider for an cube indented on the top.
net.minecraft.client.guiFont#prepareBackground- Creates a text effect for the given rectangle with the given color.GuiGraphicsExtractortextWithWordWrapnow returns the nextinty position free after wrappingsetTooltipForNextFrame,tooltipnow have an overload that takes in abooleanof whether to have a bit more space between the first line and the rest
net.minecraft.client.gui.componentsAbstractSelectionList#INWORLD_MENU_LIST_BACKGROUNDis nowpublicfromprivateRealmsButton- A button for adding a new realm.ScrollableLayout#getScrollAmount- The amount the layout has been scrolled.SubtitleOverlay$Subtitle#getClosest->getBestSubtitleCandidate
net.minecraft.client.gui.components.debugDebugEntryPlayerSpeed,DebugScreenEntries#PLAYER_SPEED- A debug entry that displays the camera entity's movement speed.DebugEntryPostEffect->DebugEntryPostEffects, now listing all active post effectsDebugScreenEntries#POST_EFFECT->POST_EFFECTS
DebugEntrySystemSpecs#getCpuInfo- Information about the current CPU.
net.minecraft.client.gui.components.debugchartAbstractDebugChart#extractRenderStatenow takes in anintfor the screen heightProfilerPieChart#extractRenderStatenow takes inints for the scaled screen width and height
net.minecraft.client.gui.components.events.GuiEventListener#capturesInput- Whether this listener captures user input.net.minecraft.client.gui.components.tabs.TabNavigationBarno longer implementsNarratableEntry,Renderablenet.minecraft.client.gui.font.FontTexture$Nodeis removednet.minecraft.client.gui.narrationNarrationElementOutput#narrationTrigger- How the narration for the element is triggered.NarrationTrigger- The possible triggers for narration of an element.ScreenNarrationCollector#updatenow takes in theNarrationTrigger
net.minecraft.client.gui.screensConfirmLinkScreennow takes in aURIinstead of aStringconfirmLinkNowmethods that take in aStringfor the URI are removedconfirmLinkmethods that take in aStringfor the URI are removed
MultiplayerOptionsScreenclass is removed- Replaced by
WorldOptionsScreen
- Replaced by
PrivacyConfirmLinkScreennow takes in aURIinstead of aStringconfirmLinkNow(Screen, String)is removed
ScreenisInputCaptured- If one of the screen elements are currently capturing user input.fillCrashDetailsis removedscheduleNarration- Schedules immediate narration by the system.updateNarratorStatusnow takes in theNarrationTrigger
net.minecraft.client.gui.screens.inventoryAbstractSignEditScreennow takes in aSignTextSlotinstead of abooleanfor if its front textHangingSignEditScreennow takes in aSignTextSlotinstead of abooleanfor if its front textSignEditScreennow takes in aSignTextSlotinstead of abooleanfor if its front textDifficultyButtons->WorldOptionsScreen$DifficultyButtonsOptionsScreenno longer implementsHasGamemasterPermissionReaction- The constructor no longer takes in the
booleanfor whether the player is in a world
- The constructor no longer takes in the
WorldOptionsScreen->.screens.WorldOptionsScreen
net.minecraft.client.gui.screens.options.controls.KeyBindsScreen#refreshKeybindLabels- Refreshes the keybind information.net.minecraft.client.gui.screens.social.PresenceHandler#sendOfflinePresence- Sends that the user is currently offline.net.minecraft.client.inputInputQuirksSIMULATE_RIGHT_CLICK_WITH_LONG_LEFT_CLICK->EMULATE_RIGHT_CLICK_WITH_CTRL_KEYSHIFT_INVERTS_SCROLL_AXIS- Whether pressing shift inverts the scroll axis.isQuitShortcutDown- Whether the quit shortcut is currently being pressed.keyboardTranslationKey- Provides the translation key for the key modifier.
InputWithModifiersNOT_DIGITis removedshortcutKey- The semantic key pressed.getDigitis removed
KeyEvent#scancode->keycode- This differs from GLFW events, where
keywas the semantic value whilescancodeis the physical location value; now,keyis the physical location value whilekeycodeis the semantic value.
- This differs from GLFW events, where
PreeditEvent#createFromCallback->fromSdlTextEditing, not one-to-one
net.minecraft.client.model.HumanoidModel#setupSwimAnimation- Sets up the swim animation.net.minecraft.client.model.effects.SpearAnimationsthirdPersonHandUsenow takes in theHumanoidArminstead of abooleanindicating if its the right armthirdPersonAttackHandnow takes in thefloatanimation progress
net.minecraft.client.model.monster.slime.SulfurCubeModelnow extendsEntityModel<SulfurCubeRenderState>and implementsHeadedModelnet.minecraft.client.model.monster.zombieAbstractZombieModelclass is removedGiantZombieModelnow extendsHumanoidModelZombieModelnow extendsHumanoidModel
net.minecraft.client.model.object.cushion.CushionModel- An entity model for the cushion.net.minecraft.client.multiplayerClientChunkCache#replaceWithPacketDatanow takes in theClientboundLevelChunkPacketDatainstead for the rawFriendlyByteBuf, heightmapMap, and block entityConsumerClientLevel#addBreakingBlockEffect->addBreakingBlockEffects, taking in abooleanfor whether to play soundMultiPlayerGameModecreatePlayernow takes in anItemActivationpiercingAttacknow takes in aSwingAnimation
net.minecraft.client.particleFallingLeavesParticlenow extendsFallingParticle$PoplarProvider- A provider for poplar falling leaves.
FallingParticle- A particle that falls like a leaf.FireworkParticles$Starternow takes in abooleanfor whether to play soundSingleQuadParticle$Layernow takes in a nullableOitPipelineSetSoulParticle->EmissiveRisingParticle, not one-to-one
net.minecraft.client.playerFirstPersonHandsAndItems- A representation of the items in first person mode, including their relative heights.ItemActivation- A representation of an activated item (e.g., totems).LocalPlayernow takes in anItemActivationitemActivation- Handles when an item should be activated.itemUsed,firstPersonHandsAndItems- Handles first person item views.sendChanges- Sends changes from the client to the server.drop->MultiPlayerGameMode#dropItem, not one-to-onesetActivePostEffects,getActivePostEffects- Handles the post effects applied to the player.
net.minecraft.client.rendererBindGroupLayoutsMATRICES_PROJECTIONis removedTERRAIN_INFO- Layout for terrain shaders.GLINT_SAMPLER- Layout for overlaying glints.DEPTH_BOUNDS_SAMPLER- Layout for handling the depth bounds within order-independent transparency pipelines.OIT_COEFFS_DEPTH_BOUNDS_SAMPLER,SAMPLER0_OIT_COEFFS_DEPTH_BOUNDS_SAMPLER,SAMPLER0_SAMPLER2_OIT_COEFFS_DEPTH_BOUNDS_SAMPLER,CLOUD_INFO_OIT_COEFFS_DEPTH_BOUNDS_SAMPLER- Layouts for specific uniforms used in order-independent transparency pipelines.
CloudRendererrender->preparerenderhas been split off to only handle the rendering of the clouds
renderOit- Renders with order-independent transparency.
DebugCrosshairRenderer#rendernow takes in the color and depthGpuTextureViewDynamicGpuDataStorage- A storage handler for writing dynamic data (e.g. uniforms, push constants), to the GPU.DynamicGpuDataStorageNonMapped- A data storage that writes data to separate CPU and GPU buffers instead of a ring buffer.DynamicUniformsreplaced byDynamicGpuDataDynamicUniformStoragereplaced byDynamicGpuDataStorageMappedGameRenderernow implementsResourceManagerReloadListenerPROJECTION_3D_HUD_Z_FARis removedEND_OF_FRAME_POST_EFFECT- Identifier for the end of frame post effect.itemInHandRenderer->firstPersonHandsAndItemsRenderer- The constructor now takes in the
ItemModelResolver clearPostEffect- >clearSpectatedEntityPostEffecttogglePostEffect->toggleSpectatorPostEffectpreloadUiShaderis nowstatic, taking in theResourceManagerinstead of aResourceProviderspectatedEntityPostEffect,getRequestedPostEffects,getAppliedPostEffects- Getters for the post effects applied.renderno longer takes in any argumentsrenderLevelno longer takes in any argumentsdisplayItemActivation->LocalPlayer#displayItemActivationuseImprovedTransparency- Whether the game should attempt to render with order-independent transparency.
GlobalSettingsUniform#updatenow takes in afloatfor the world's partial tick instead of theDeltaTrackerItemInHandRenderer->FirstPersonHandsAndItemsRenderer, not one-to-oneLevelRendererOIT_WAVELET_RANK,OIT_COEFFICIENT_COUNT,OIT_TRANSMITTANCE_TARGET_COUNT- Order-independent transparency constants.renderno longer takes in theDeltaTrackeror model viewMatrix4fc, instead taking in abooleanfor whether to require consistent depthprepareChunkRendersnow takes in abooleanfor whether to respsect translucency orderingprepareChunkRendersIndirect- Prepare the chunk section to render using indirect draw calls.doEntityOutline->blitEntityOutlineisSectionCompiledAndVisiblenow takes in thelongchunk fade durationentityOutlineTarget,translucentTarget,itemEntityTarget,particlesTarget,weatherTarget,cloudsTargetare removedisChunkRenderingUsingMultiDrawIndirect- If the chunk renderer will use indirect multidraw calls.addTransientBlock,removeTransientBlocksInSection- Handles transient block management.
LevelTargetBundleTRANSLUCENT_TARGET_ID,ITEM_ENTITY_TARGET_ID,PARTICLES_TARGET_ID,WEATHER_TARGET_ID,CLOUDS_TARGET_IDare removedSORTING_TARGETSis removedtranslucent,itemEntity,particles,weather,cloudsare removedalwaysOnTopDepth- Resource handle for render targets that should always appear on top.depthBounds,depthBoundsCulled,transmittance,accumulate,oitCloudDepth,oitTerrainWithWaterPatchDepth- Resource handles for order-independent transparency rendering.
OrderedSubmitNodeCollectorsubmitTextBackground- Submits a rectangle as a font effect.submitModelnow takes in aUvMappinginstead of theTextureAtlasSpritesubmitModeloverloads no longer take in aModelFeatureRenderer$CrumblingOverlaysubmitCrumblingOverlay- Submits a crumbling overlay for an entity model.submitModelPartnow takes in aUvMappinginstead of theTextureAtlasSpritesubmitModelPartoverloads no longer take in aModelFeatureRenderer$CrumblingOverlaysubmitBreakingBlockModelnow takes in abooleanof whether the block is translucentsubmitItemnow takes in anItemQuadsinstead of a list ofBakedQuads
PostChainid- The identifier of the post effect.getReferencedExternalTargets- Gets any referenced targets in the post effect.closePersistentTargets- Destroys the buffers for any persistent targets.
RenderPipelinesOIT_DEPTH_BOUNDS_SNIPPET,OIT_TRANSMITTANCE_SNIPPET,OIT_ACCUMULATE_SNIPPET- Snippets for order-independent transparency.SOLID_TERRAIN_MULTIDRAW- Pipeline for drawing solid terrain with multidraw calls.WIREFRAME_MULTIDRAW- Pipeline for drawing wireframes with multidraw calls.CUTOUT_TERRAIN_MULTIDRAW- Pipeline for drawing cutout terrain with multidraw calls.TRANSLUCENT_TERRAIN_MULTIDRAW- Pipeline for drawing translucent terrain with multidraw calls.OIT_*- Pipelines for drawing with order-independent transparency.ARMOR_TRANSLUCENT->WOLF_ARMOR_CRACKSENTITY_SHADOW- Pipeline for drawing an entity's shadow.GLINT_SNIPPET,GLINT_SPECIAL_SNIPPET,ARMOR_CUTOUT_NO_CULL_GLINT,ENTITY_SOLID_GLINT,ITEM_CUTOUT_GLINT,ITEM_CUTOUT_GLINT_SPECIAL,ITEM_TRANSLUCENT_GLINT,ITEM_TRANSLUCENT_GLINT_SPECIAL- Snippets and pipelines for applying the glint decal.TEXT_BACKGROUND,TEXT_BACKGROUND_SEE_THROUGHare removedLINES_TRANSLUCENTreplaced byLINES_TRANSLUCENT_NO_DEPTH_WRITELINES_TRANSLUCENTnow uses the default depth stenctil state
WEATHER_DEPTH_WRITE,WEATHER_NO_DEPTH_WRITEreplaced byWEATHERBLIT_DEPTH_BOUNDS,BLIT_DEPTH_DURING_DEPTH_BOUNDS,BLIT_DEPTH,INTEGRATE_DEPTH- Pipelines for handling depth bounds during order-independent transparency.getStaticPipelines->requiredPipelinesoptionalPipelines- Pipelines that are optionally used by the game.
ScreenEffectRenderernow takes in theGameRendererinstead of theMinecraftinstanceITEM_ACTIVATION_ANIMATION_LENGTHis removedsubmitno longer takes in thebooleanfor first person and sleeping, instead taking in thePlayerRenderStateandCameraRenderStatetickis removedresetItemActivation->LocalPlayer#resetItemActivationdisplayItemActivation->LocalPlayer#displayItemActivation
ShaderManagernow implementsPreparableReloadListenerinstaed of extendingSimplePreparableReloadListenerSHADER_INCLUDE_PATHis nowpublicfromprivateSHADER_INCLUDE_EXTENSION,SHADER_INCLUDE_CONVERTER- References to include shaders.listAllIncludes- List all include shaders.isPostEffectValid- Checks if a post effect is only targetting valid render targets.getShader->ShaderSource#getShadergetAvailablePostEffects- Returns all known post effects.
SheetsARMOR_TRIMS_SHEET,armorTrimsSheetare removed*Glint*Sheet- Glint sheets.
SkyRendererextractRenderStaterenderSkyDisc->renderrenderSunriseAndSunsetis nowprivatefrompublicrenderEndSkyis nowprivatefrompublicrenderEndFlashis nowprivatefrompublic
SpriteCoordinateExpanderis now a record- The constructor takes in a
UvMappinginstead of aTextureAtlasSprite
- The constructor takes in a
StagedVertexBufferrequestIndexCount- Increases the maximum size of the index buffer to hold the entire draw.$ExecuteInfo#indexBuffer->customIndexBufferindexBuffercalls tocustomIndexBufferbefore replicating default behavior
SubmitNodeCollectionseeThroughNameTagsmerged intoseeThroughgizmosis removed- Submits solid gizmos to
solid, and tranlucent gizmos totranslucentGizmos
- Submits solid gizmos to
alwaysOnTop->alwaysOnTopGizmosoitTranslucent- Order-independent transparency storage.
SubmitNodeStoragesetUseImprovedTransparency- Toggles whether to use order-independent transparency.seeThrough- The translucent features that can be seen through.
WeatherEffectRendererrender->preparerenderhas been split off to only handle the rendering of the weather
renderOit- Renders with order-independent transparency.
WorldBorderRendererrender->preparerenderhas been split off to only handle the rendering of the world border
renderOit- Renders with order-independent transparency.
net.minecraft.client.renderer.blockentityAbstractEndPortalRenderer#submitSpecialnow takes in the outline colorBannerRenderer#submitPatternsno longer takes in theModelFeatureRenderer$CrumblingOverlaySkullBlockRenderer#getPlayerSkinRenderTypeCutout- Gets the entity cutoutRenderTypefor the given texture.
net.minecraft.client.renderer.chunkChunkSectionLayer#pipelinenow takes in abooleanfor whether to use a pipeline with multidraw calls.ChunkSectionLayerGroup#outputTargetis removedChunkSectionsToRenderis now an abstractclassfrom arecordrenderGroupnow takes in theGpuTextureViewatlas and whether to render as a wireframebooleanrender,renderOit- Renders the chunk sections.$DrawIndirect- Renders the chunk sections using indirect draw calls.$DrawSeparate- Renders the chunk sections using normal draw calls.$GpuMultiDrawIndexedIndirect- A record that contains the buffer data for indirect multidraw calls.
CompiledSectionMeshnow takes in alongfor the nanosecond start time for the compile taskSectionMesh#getCompileTaskStartTime- When the mesh had started compiling.SectionRenderDispatcher$RenderSectiongetVisibilitynow takes in thelongfade durationsetFadeDurationis removedsetWasPreviouslyEmpty,wasPreviouslyEmptyare removedupdateUploadTime- Updates the upload time to the current time in milliseconds if not set.
net.minecraft.client.renderer.culling.Frustum#getNearPlaneBounds- Gets the bounding box for the near plane.net.minecraft.client.renderer.entityCushionRenderer- Renderer for a cushion.EntityRenderDispatcherno longer takes in theMinecraftinstance, instead taking in thePalettedTextureManagergetPlayerRenderer->getRenderer, taking in theAvatarRenderStateinstead of theAbstractClientPlayershouldRendernow takes in the partial tickgetItemInHandRendereris removed
EntityRenderershouldRendernow takes in the partial tickgetBoundingBoxForCullingnow takes in the partial tick
EntityRendererProvider$Contextnow takes in thePalettedTextureManagerHumanoidMobRenderer#usesSpearPose- Returns whether the entity is swinging a spear.SulfurCubeRenderer#CUSTOM_HEAD_TRANSFORMS- Transforms when wearing a head.
net.minecraft.client.renderer.entity.layersCustomHeadLayerSKULL_SCALEis nowpublicfromprivate$Transformsnow takes in thefloatvertical scale and a function for resolving the player skinTRANSLUCENT_PLAYER_SKIN_RESOLVER,CUTOUT_PLAYER_SKIN_RESOLVER- Resolvers for rendering a player's skin.
EquipmentLayerRenderernow takes in aPalettedTextureManagerinstead of aTextureAtlas
net.minecraft.client.renderer.entity.stateArmedEntityRenderStateattackArm,swingAnimationTypemerged intocurrentSwingattackTime->swingAnimationgetArmPose- Gets the pose for the given arm.
CushionRenderState- The render state for a cushion.IllagerRenderState#attackAnimis removed
net.minecraft.client.renderer.extractLevelExtractorisEntityVisiblenow takes in thefloatpartial tick and thelongchunk fade durationqueueTransientBlock- Adds a transient block for submission.
TransientBlock- A block that exists at a position for only a certain amount of time, by default a millisecond.
net.minecraft.client.renderer.featureFeatureRenderDispatcherrenderAllFeaturesis nowstatic, taking in theRenderPassand the$PreparedFrameinstead of theSubmitNodeStorage$PreparedFrame#execute*methods now take in theRenderPassexecuteWaterMask,hasAnyWaterMask- Handles any water masks.executeOit- Renders any order-independent transparency.executeSeeThrough,hasAnySeeThrough- Handles any see through objects.hasAnyAlwaysOnTopis removedisEmpty- Checks if there's nothing submitted for rendering.
$PreparedGroup#executenow takes in theOitStageand theRenderPass
FeatureRenderer#executeGroupnow takes in theOitStageand theRenderPassItemFeatureRendererSPECIAL_FOIL_TEXTURE_SCALEis nowpublicfromprivate$Submit#hasTranslucencyis removed
ModelFeatureRenderer$Submitnow takes in aUvMappinginstead of theTextureAtlasSpriteMovingBlockFeatureRenderer$Submitnow takes in abooleanof whether to force translucencyNameTagFeatureRendererclass is removedTextFeatureRenderer$Content- Represents a specific piece of text or effect to render.$Submitnow implementsTranslucentSubmitx,y,string,dropShadow,color,backgroundColor,outlineColorhas been merged intocontent
net.minecraft.client.renderer.fog.environment.FogEnvironment#getBaseColornow returns aVector3fcinstead of anintnet.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives#isEmpty- Returns if there are no gizmos submitted for rendering.net.minecraft.client.renderer.item.ItemStackRenderState$LayerRenderState#prepareQuadListreplaced bysetQuadsnet.minecraft.client.renderer.oitOitPipelineSet- A set of pipelines for rendering using order-independent transparency.OitRenderPassProvider- A provider for creating theRenderPasses for order-independent transparency.OitStage- The stages involved for rendering with order-independent transparency.
net.minecraft.client.renderer.rendertypeOutputTargetclass is removedPreparedRenderTypenow takes in aStringname and aOitPipelineSetinstead of anOutputTargetdrawFromBuffer(StagedVertexBuffer$ExecuteInfo)now takes in aRenderPassdrawFromBuffer(GpuBuffer...)is removeddrawFromBufferOit- Draws the render type using order-independent transparency.
RenderSetup$RenderSetupBuildersetOutputTargetis removedsetOutlinenow has an overload that takes in theStringtexture namesetOitPipelines- Sets the pipelines that render via order-independent transparency.withForcedSolidModelPhase- Forces a non-solid model to render as a solid model.
RenderTypeoutputTargetis removedforceSolidModelPhase- Whether to force a non-solid model to render as a solid model.
RenderTypescreateArmorDecalCutoutNoCullsplit intoarmorCutoutNoCullGlint,armorTrimarmorTranslucentreplaced bywolfArmorCracks*Glint*- Glint overlay render types.entityTranslucentCullItemTargetis removedentityTranslucentCull- Entity rendering with translucency and culling.entityTranslucentEmissive(Identifier, boolean)is removedarmorEntityGlint,glintTranslucent,glint,entityGlintare removedtextBackground,textBackgroundSeeThroughare removedlinesTranslucentNoDepthWrite,linesDepthBias- Line render types.
net.minecraft.client.renderer.state.GameRenderStaterequestedPostEffects- Post effects used.shouldRenderLevel- Whether the level should be rendered.readyForLevelRendering- If the level is ready to be rendered.useShaderTransparencyis removed
net.minecraft.client.renderer.state.gui.pipGuiProfilerChartRenderStatenow takes in aMatrix3x2fcposePictureInPictureRenderState#getBoundsnow has an overload that takes in theMatrix3x2fcpose
net.minecraft.client.renderer.state.levelCameraRenderStateisFirstPerson- If the camera is showing from a first person perspective.cameraEntityPartialTicks- The partial tick of the camera entity.
FirstPersonHandsAndItemsRenderState- The first person render state for held items.LevelRenderStateplayerRenderState- The render state of the client player.worldPartialTicks- The partial tick of the worldrenderWireframeTerrain- Whether the terrain should be rendered as a wireframe.shouldUseMultiDrawIndirectForTerrain- Whether indirect multidraw calls should be used to render the terrain.
PlayerRenderState- The render state of the client player.SkyRenderState#sunriseAndSunsetColor,skyColorare nowVector4fcs instead ofintsTransientBlockRenderState- The render state of a moving block that lives for a certain amount of time.
net.minecraft.client.renderer.textureDynamicAtlasTree- A tree for dynamically allocating texture space within a specific bounds.DynamicAtlasTreeSlot- A node of theDynamicAtlasTreethat represents a slot to take.MipmappedTexture- A reloadable texture that contains all mipmaps up to the specified level.ReloadableTexture#setSampler- Sets the sampler based on its contents.TextureAtlasSpritenow implementsUvMappingwrap->UvMapping#wrap
TextureManager#INTENTIONAL_MISSING_TEXTUREis removedUvMapping- An interface that represents that an object can be mapped to a UV coordinate.
net.minecraft.client.resources.metadata.texture.PaletteMetadataSection- Palette metadata for a texture.net.minecraft.client.resources.modelEquipmentClientInfonow takes in a list of$TrimOverrides$Builder#replaceTrimPalette- Replaced the palette of a specific trim material with the given identifier.$TrimOverride- An override to replace oneTrimMaterialpalette with another.$TrimPredicate- The predicate to match to replace aTrimMaterial's palette.
ModelBakeryDESTROY_STAGE_COUNT,DESTROY_STAGES,BREAKING_LOCATIONSare nowprivatefrompublicDESTROY_TYPES_OIT- The destroy types used during order-independent transparency pipelines.
net.minecraft.client.resources.model.cuboidCuboidModelElementnow takes in a nullableDirectionfor the shade instead of abooleanFaceBakery#bakeQuadnow takes in a nullableDirectionfor the shade instead of aboolean
net.minecraft.client.resources.model.geometryBakedQuad$MaterialInfonow takes in a nullableDirectionfor the shade instead of aboolean, along withRenderTypes for the item glint and special item glintofnow takes in a nullableDirectionfor the shade instead of aboolean
ItemQuads- The baked quads of an item broken into solid and translucent groups.
net.minecraft.client.resources.model.spriteMaterial#withSuffix- Suffixes the sprite of the material.MaterialBakeris no longer abstract- The constructor now takes in
SpriteLoader$Preparationsfor the block and item atlas, and now the missingTextureAtlasSprite replacementForMissingMaterialis nowprivatefrompublicbake,bakeForAtlasare nowprivatefrompublic
- The constructor now takes in
net.minecraft.client.resources.palettePalette- A texture represented as an array ofints.PalettedTextureManager- A texture manager to handle the permutations of a texture for each palette.PaletteMapping- A mapping of colors in onePaletteto another.PaletteMappingCache- A cache containing the palette mappings, droping any unused entries after five minutes.
net.minecraft.data.AtlasIds#ARMOR_TRIMSis removednet.minecraft.network.protocol.gameClientboundAddTransientBlockPacket- Sends a block to the client that exists for a finite amount of time.ClientGamePacketListener#handleAddTransientBlockPacket- Handles the transient block packet.
net.minecraft.server.level.ServerPlayer#sendPostEffects,addPostEffect,clearPostEffects,getPostEffects,removePostEffect- Handles the post effects applied on the player.net.minecraft.util.PngInfonow takes in abytefor the bit depth and color typenet.minecraft.world.entity.player.Player#postEffects- The post effects currently applied to the player.net.minecraft.world.item.equipment.trimArmorTrim#layerAssetIdis removedMaterialAssetGrouprecord is removedTrimMaterialnow takes in anIdentifierrepresenting the palette id instead of aMaterialAssetGroupTrimMaterials$Palette- Identifiers for trim palettes.
net.minecraft.world.level.block.SignBlock#openTextEditnow takes in aSignTextSlotinstead of abooleanfor if it's front textnet.minecraft.world.level.block.entitySignBlockEntitycreateDefaultSignTextis removedisFacingFrontText->getSlotPlayerIsFacing, returning theSignTextSlotgetTextnow takes in aSignTextSlotgetFrontText,getBackTextare removedupdateSignText,updateTextnow take in aSignTextSlotinstead of abooleanfor if it's front textsetTextis removedcanExecuteClickCommands,executeClickCommandsIfPresentnow take in aSignTextSlotinstead of abooleanfor if it's front text
SignTextnow takes in lists ofComponentmessages instead of arraysDIRECT_CODEC->CODECSTREAM_CODEC- The network codec.FRONT_TEXT,BACK_TEXT- Tooltip providers for the text on a given side of the sign.EMPTY- A sign with no text.setHasGlowingText->withGlowingTextsetColor->withColorsetMessagemethods are removedhasMessagenow takes in abooleanfilter instead of thePlayergetMessagesnow returns a list ofComponents instead of an arrayhasAnyClickCommandsnow takes in abooleanfilter instead of thePlayerhasEditableText- Whether the sign has text that can still be editted.asMutable,$Mutable- A mutable version of the sign components.createTooltip- Creates the getter for the sign text tooltips.
SignTextSlot- The location of the text on the sign.
Registries and Data Components
Many different registries and data components have been rewritten in a variety of different methods. As they are so intertwined, they have combine them all into one mega section, similarly to the usual client updates.
Reloadable Datapack Registries
A new layer has been introduced into the datapack registry process that allows for some datapack registries to be marked as reloadable (can be reloaded via /reload command). As such, LootTables, LootItemConditions, ContextFloatProviders, ContextIntProviders, LootItemFunctions, SlotSources, Advancements, and Recipes are now datapack registries. Adding a new reloadable datapack registry requires adding to the RegistryDataLoader#RELOADABLE_REGISTRIES list.
With this change comes many other changes, especially for data generation and implementation details, which have their own sections below. However, the general gist is that most ResourceKey or direct value references have been replaced with either a Holder-wrapped, or HolderSet-wrapped registry object. Which is chosen depends entirely on the specific use case.
Registry Bootstrap "Providers"
Since data generation for datapack registry entries are handled through RegistriesDatapackGenerator, reloadable registries now no longer have their own DataProviders. Instead, the provider classes now implements either SingleRegistryBootstrap or MultiRegistryBootstrap to 'provide' their entries to RegistriesDatapackGenerator#forReloadableLayer.
SingleRegistryBootstrap, previously RegistrySetBuilder$RegistryBootstrap, is the familiar consumer that takes in a BootstrapContext to register entries to. Both LootTableProvider and AdvancementProvider now implement SingleRegistryBootstrap, setting the generic to the registry object type.
This means that their underlying implementations are completely different.
AdvancementProvider now takes in a list of AdvancementSubProvider$Factorys, which construct the AdvancementSubProvider with the BootstrapContext supplied to the main provider. AdvancementSubProvider is now an abstract class as well, taking in the BootstrapContext to be used as part of the no argument generate method. If another advancement needs to be referenced for a parent, only the Identifier is now required.
public class ExampleAdvancementSubProvider extends AdvancementSubProvider {
// The constructor with the bootstrap context
public ExampleAdvancementSubProvider(BootstrapContext<Advancement> output) {
super(output);
}
@Override
public void generate() {
// The output can be obtained via `this.output`.
// Additionally, `AdvancementSubProvider` already provides fielded
// access to the damage types registry via `this.damageTypes`.
Holder.Reference<Advancement> example = Advancement.Builder.advancement()
// Set a parent to another advancement.
.parent(Identifier.withDefaultNamespace("adventure/sleep_in_bed"))
// Add whatever other information.
// Register the advancement for generation.
.save(this.output, "examplemod:example_advancement");
}
}
// For some RegistrySetBuilder registry passed to a `RegistriesDatapackGenerator`:
registry.add(
Registries.ADVANCEMENT,
// The advancement provider to register.
new AdvancementProvider(
// The list of sub providers to generate.
List.of(
ExampleAdvancementSubProvider::new
)
)
);
LootTableProvider and its associated LootTableSubProvider are in a slightly different situation. Most of the implementation logic is quite similar in nature, with the main difference being some minor changes to the underlying interfaces. If you are not implementing your own custom provider methods, then you will likely only have to change the constructor and provider addition.
If you are, here are the main points. LootTableProvider$SubProviderEntry now takes in a LootTableSubProvider$Factory similar to the advancement provider, except that this factory takes in a LootTableSubProvider$Context. This is a wrapper around the BootstrapContext<LootTable> meant to set the random sequence and param set for you. Meanwhile, LootTableSubProvider replaces generate with a no argument run. Instead you are supposed to store the LootTableSubProvider$Context and call accept, similar to how the output consumer from generate was handled.
public class ExampleLootSubProvider implements LootTableSubProvider {
protected final LootTableSubProvider.Context output;
public ExampleLootSubProvider(LootTableSubProvider.Context output) {
// Store the output
this.output = output;
}
@Override
public void run() {
// Write the loot table.
this.output.accept(
// The registry key for the table.
ResourceKey.create(Registries.LOOT_TABLE, Identifier.fromNamespaceAndPath("examplemod", "example_table")),
// A builder for the loot table.
// Call whatever methods desired to add pools, conditions, etc.
LootTable.lootTable()
);
}
}
BlockLootSubProvider and EntityLootSubProvider are similar, except they take in the LootTableSubProvider$Context instead of the HolderLookup$Provider. They each provide the common HolderGetters that is used to get the objects. The main difference is that some elements replace the LootItemCondition$Builder with a Holder<LootItemCondition> depending on if the condition is now datapack registered instead of inlined. But otherwise, they are functionally the same.
public class ExampleBlockLoot extends BlockLootSubProvider {
public ExampleBlockLoot(LootTableSubProvider.Context output) {
super(
// Items that are explosion resistant.
Set.of(),
// The feature flags to check for generation.
FeatureFlags.REGISTRY.allFlags(),
// The passed in context.
output
);
}
@Override
protected void generate() {
// More or less same as prior versions.
}
}
Then, all you need to do is add them to the provider with the desired ContextKeySet:
// For some RegistrySetBuilder registry passed to a `RegistriesDatapackGenerator`:
registry.add(
Registries.LOOT_TABLE,
// The loot table provider to register.
new LootTableProvider(
// The built in loot tables to check for.
Set.of()
// The list of sub providers to generate.
List.of(
new LootTableProvider.SubProviderEntry(ExampleLootSubProvider::new, LootContextParamSets.SELECTOR),
new LootTableProvider.SubProviderEntry(ExampleBlockLoot::new, LootContextParamSets.BLOCK)
)
)
);
One caveat is that validation is no longer handled in the provider itself. Rather it is checked when constructing the reloadable lookup through VanillaRegistries#validateLootData. Depending on the circularness of your registry entries (e.g. referring to other loot tables in loot tables), you may want to perform a similar validation, which will likely have to be wrapped or injected in somehow.
MultiRegistryBootstrap handles generating registry entries for multiple registries in the same provider. The registries it generates for are requested in requestedRegistries via their ResourceKeys. Then run is used to get the BootstrapContexts required for registration.
This is currently only used by RecipeProvider since it generates both recipes and their associated advancements at the same time. Given the bootstrap nature, RecipeProvider$Runner is removed. Instead, we create our own MultiRegistryBootstrap to handle the recipe building.
RecipeProvider now takes in the BoostrapContexts for the recipe and advancement registries. The RecipeOutput is created within the construtor, acting as our BootstrapContextAccess to get any other required registries. Actually generating the recipes is more or less the same: override buildRecipes and call RecipeOutput#accept with the recipe to register, or more commonly using RecipeBuilder#save. The MultiRegistryBootstrap can be created as an anonymous class where RecipeProvider#buildRecipes is called within run:
public class ExampleRecipeProvider extends RecipeProvider {
// The constructors with the desired outputs.
public ExampleRecipeProvider(BootstrapContext<Recipe<?>> recipeOutput, BootstrapContext<Advancement> advancementOutput) {
super(recipeOutput, advancementOutput);
}
@Override
protected void buildRecipes() {
// Call whatever methods to generate the recipes.
}
// ...
// Construct the registry bootstrap.
public static MultiRegistryBootstrap create() {
return new MultiRegistryBootstrap() {
@Override
public Set<ResourceKey<? extends Registry<?>>> requestedRegistries() {
// Return the registries we are adding entries to.
return Set.of(Registries.RECIPE, Registries.ADVANCEMENT);
}
@Override
public void run(MultiRegistryBootstrap.BootstrapGetter registries) {
// Run the recipe provider.
new ExampleRecipeProvider(registries.get(Registries.RECIPE), registries.get(Registries.ADVANCEMENT)).buildRecipes();
}
};
}
}
// For some RegistrySetBuilder registry passed to a `RegistriesDatapackGenerator`:
registry.add(
Registries.RECIPE,
// The bootstrap to register.
ExampleRecipeProvider.create()
);
Removal of ContextAwarePredicate
ContextAwarePredicate was originally a wrapper around a list of LootItemConditions for use in advancement criteria triggers. Now, ContextAwarePredicate has been completely removed, replaced by the Holder<LootItemCondition>:
// For some trigger implementation
public record ExampleTriggerInstance(Optional<Holder<LootItemCondition>> player) implements SimpleCriterionTrigger.SimpleInstance {
// ...
}
Registering ContextKeySets for Some Reason
With the transition to reloadable registries, A new registry has been added for ContextKeySets used by the loot table. These are still defined in LootContextParamSets, meaning that the behavior remains almost identical. However, it now validates that all ContextKeys (e.g. the ones defined in LootContextParams) are added as required keys within LootContextParamSets#ALL_PARAMS.
While this makes it more difficult to add custom ContextKeys within a new loot ContextKeySet, this validation only occurs once when Bootstrap#bootStrap is called. Still, due to validation, it is highly recommended to both inject into LootContextParamSets#ALL_PARAMS your custom ContextKey before registering your specific loot ContextKeySet.
New Loot Data Types
With the new reloadable registries also comes associated LootDataTypes for SlotSource (LootDataType#SLOT_SOURCE), ContextFloatProvider (LootDataType#FLOAT_PROVIDER), and ContextIntProvider (LootDataType#INT_PROVIDER).
As a refresher, LootDataTypes are typically used for validation and context tracking. All loot data is validated after registration, checking for any non-obvious issues like recursion or parameters not specified in the used ContextKeySet. Then, when generating the loot, elements are tracked by visitation using LootContext#pushVisitedElement and LootContext#popVisitedElement to ensure that an element is only visited once and is not recursing on itself.
Of these, all three new data types validate against LootContextParamSets#ALL_PARAMS. However, only LootDataType#SLOT_SOURCE is tracked for visitation when running the /item commands.
Reorganizing Pool Containers
The underlying structure of LootPoolEntryContainers has been slightly reorganized to separate the difference between a single entry vs one that provides a set of entries.
For this, LootPoolSingletonContainer was split into two classes: UniformContainerBase which handles the entry(s) and their weight(s), and its subclass SingleEntryContainerBase which indicates that the container only provides a single entry. LootItem, DynamicLoot, SlotLoot, and EmptyLootItem all extend SingleEntryContainerBase, with its methods being pretty much identical to LootPoolSingletonContainer, aside from the reloadable registry changes.
For TagEntry and NestedLootTable, a new UniformContainerBase subtype was added called ExpandableContainerBase, which, if expand is true, allows an entry to be treated as a list of entries of one item each to select from, rather than one entry that provides all items:
// A basic example showing the implementation difference.
public class ExampleExpandableEntry extends ExpandableContainerBase {
// The map codec to register
public static final MapCodec<ExampleExpandableEntry> MAP_CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
RegistryCodecs.holderSet(Registries.ITEM).fieldOf("items").forGetter(e -> e.tag)
).and(expandableFields(instance))
.apply(instance, ExampleExpandableEntry::new)
);
private final HolderSet<Item> items;
// The last five parameters are required for each expandable
// container.
public ExampleExpandableEntry(HolderSet<Item> items, boolean expand, int weight, int quality, Optional<Holder<LootItemCondition>> condition, Optional<Holder<LootItemFunction>> modifier) {
super(expand, weight, quality, condition, modifier);
this.items = items;
}
@Override
public MapCodec<ExampleExpandableEntry> codec() {
return MAP_CODEC;
}
@Override
protected boolean addExpandedEntries(Consumer<LootPoolEntry> output) {
// Adds as a separate entry per item.
// As separate entries, they can each be rolled individually, applying with
// the weight, conditions, and modifiers for each.
this.items.forEach(item -> output.accept(new UniformContainerBase.EntryBase() {
@Override
public void createItemStack(Consumer<ItemStack> output, LootContext context) {
output.accept(new ItemStack(item));
}
}));
// Returns whether the entries were added successfully.
return true;
}
@Override
protected boolean addUnexpandedEntry(Consumer<LootPoolEntry> output) {
// Adds a single entry for all items.
// As a single entry, if this is selected, all values inside will be provided.
output.accept(new UniformContainerBase.EntryBase() {
@Override
public void createItemStack(Consumer<ItemStack> output, LootContext context) {
ExampleExpandableEntry.this.items.forEach(item -> output.accept(new ItemStack(item)));
}
});
// Returns whether the entries was added successfully.
return true;
}
// A basic helper to construct the builder for data generation.
public static UniformContainerBase.Builder<?> contents(boolean expand, Holder<Item>... items) {
return simpleBuilder(
(weight, quality, conditions, functions) -> new ExampleExpandableEntry(
HolderSet.direct(items), expand, weight, quality, conditions, functions
)
);
}
}
Loot Conditions and Functions: Tweaks and Registrations
With the addition of reloadable registries, the LootItemConditions and LootItemFunctions have some minor tweaks to better fit the datapack registry design. As a result, some conditions are referenced registered instead of inlined, like checking whether a tool can silk touch or shear (see LootPredicates).
// A basic example.
// For actually registering loot tables, it should be done
// through the `LootTableSubProvider`.
private static void registerTables(BootstrapContext<LootTable> context) {
LootTable.lootTable().withPool(
LootPool.lootPool()
// Reference a registered condition.
.when(context.lookup(Registries.PREDICATE).getOrThrow(LootPredicates.TOOL_CAN_SILK_TOUCH))
// ...
);
}
For LootItemConditions, the ConditionUserBuilder can now take in a Holder-wrapped condition in its when clause. When composing a condition within the loot table context, any list of conditions are merged into a single inlined holder via ConditionUserBuilder#buildCondition. The actual implementation of the conditions remain exactly the same.
For LootItemFunction, the common superclass LootItemConditionalFunction also takes in a single optional, Holder-wrapped condition instead of a list due to composition changes. Similarly, the FunctionUserBuilder can now take in a Holder-wrapped function in its apply clause. Any list of functions are merged into a single inlined holder via FunctionUserBuilder#buildFunction, and as such, LootItemFunction#decorate now takes in that optional, Holder-wrapped function the modify the dropped outputs. If implementing a custom LootItemConditionalFunction, the constructor will need to be updated:
// A basic conditional function.
public class NoOpFunction extends LootItemConditionalFunction {
// Takes in a single condition that is composed together rather than
// a list.
public NoOpFunction(Optional<Holder<LootItemCondition>> condition) {
super(condition);
}
}
Registered Slot Sources
With the addition of reloadable registries, SlotSources can now be registered to Registries#SLOT_SOURCE. While there is no restriction on where a referenced
slot source can be used, vanilla only references them specifically for the /item and /execute commands. The rest are inlined within
a loot table, if used at all.
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register
public static final ResourceKey<SlotSource> EMPTY = ResourceKey.create(
Registries.SLOT_SOURCE,
Identifier.fromNamespaceAndPath("examplemod", "empty")
);
builder.add(Registries.SLOT_SOURCE, bootstrap -> {
bootstrap.register(
EMPTY,
// An empty slot source.
new EmptySlotSource()
);
});
// In data/examplemod/slot_source/empty.json
{
// An empty slot source.
"type": "minecraft:empty"
}
Which can be referenced like:
// For some loot table.
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:slots",
// Replaces the inlined entry.
"slot_source": "examplemod:empty"
}
// ...
]
}
// ...
]
}
Splitting Numbers into Floats and Ints
NumberProvider which handled retrieving a float or int given some context, has now been split into two interfaces: ContextFloatProvider for floats, and ContextIntProvider for ints. Their implementations are nearly identical, just with the word float swapped out for int, and vice versa.
Both providers are Validatable and must implement getFloatUnsafe or getIntUnsafe, which returns the value and could potentially through an ArithmeticException. If the exception should be ignored, the values can be obtained using getFloat or getInt, returning 0 if the exception is thrown. Given that floats have non-finite representations, ContextFloatProvider also returns 0 if the result is non-finite, or can throw an ArithmeticException using getFloatOrThrow. To register the provider for use, a MapCodec must be created, returned by codec, and registered to BuiltInRegistries#CONTEXT_FLOAT_PROVIDER_TYPE or CONTEXT_INT_PROVIDER_TYPE.
// Some basic number providers.
public record FloatZeroValue() implements ContextFloatProvider {
public static final FloatZeroValue INSTANCE = new FloatZeroValue();
// The codec to register.
public static final MapCodec<FloatZeroValue> MAP_CODEC = MapCodec.unit(INSTANCE);
@Override
public MapCodec<FloatZeroValue> codec() {
// Links the codec to the provider implementation for
// serialization.
return MAP_CODEC;
}
@Override
public void validate(ValidationContext context) {
// If using any loot data type, validate it here.
}
@Override
public float getFloatUnsafe(LootContext random) {
// Return the value provided.
return 0f;
}
}
public record IntZeroValue() implements ContextIntProvider {
public static final IntZeroValue INSTANCE = new IntZeroValue();
// The codec to register.
public static final MapCodec<IntZeroValue> MAP_CODEC = MapCodec.unit(INSTANCE);
@Override
public MapCodec<IntZeroValue> codec() {
// Links the codec to the provider implementation for
// serialization.
return MAP_CODEC;
}
@Override
public void validate(ValidationContext context) {
// If using any loot data type, validate it here.
}
@Override
public int getIntUnsafe(LootContext random) {
// Return the value provided.
return 0;
}
}
// Register the map codecs.
Registry.register(
BuiltInRegistries.CONTEXT_FLOAT_PROVIDER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "float_zero"),
FloatZeroValue.MAP_CODEC
);
Registry.register(
BuiltInRegistries.CONTEXT_INT_PROVIDER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "int_zero"),
IntZeroValue.MAP_CODEC
);
As reloadable registries, the providers can be registed and used by referenced rather than inlined to Registries#CONTEXT_FLOAT_PROVIDER or CONTEXT_INT_PROVIDER:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource keys to register.
public static final ResourceKey<ContextFloatProvider> FLOAT_ZERO = ResourceKey.create(
Registries.CONTEXT_FLOAT_PROVIDER,
Identifier.fromNamespaceAndPath("examplemod", "zero")
);
public static final ResourceKey<ContextIntProvider> INT_ZERO = ResourceKey.create(
Registries.CONTEXT_INT_PROVIDER,
Identifier.fromNamespaceAndPath("examplemod", "zero")
);
// Add them to the appropriate provider.
builder.add(Registries.CONTEXT_FLOAT_PROVIDER, bootstrap -> {
bootstrap.register(
FLOAT_ZERO,
// Our float provider.
new FloatZeroValue()
);
});
builder.add(Registries.CONTEXT_INT_PROVIDER, bootstrap -> {
bootstrap.register(
INT_ZERO,
// Our int provider.
new IntZeroValue()
);
});
And the generated JSON:
// For some float provider.
// In `data/examplemod/worldgen/context_float_provider/zero.json`
{
// Our float provider.
"type": "examplemod:zero"
}
// For some int provider.
// In `data/examplemod/worldgen/context_int_provider/zero.json`
{
// Our int provider.
"type": "examplemod:zero"
}
Due to the many similarities bewteen the types of providers implemented, vanilla also provides some simple interfaces that can be implemented in addition to the provider of your choice. These implement Validatable#validate along with providing a way to construct the MapCodec. The other methods defined typically match the signature of an associated argument in a record constructor.
// A provider using a basic interface.
// Since we are modifying one value of another provider, we use `UnaryProvider`.
// `input` implemented by the record argument.
public record CubeRoot(Holder<ContextFloatProvider> input) implements ContextFloatProvider, UnaryProvider<ContextFloatProvider> {
// The codec to register.
public static final MapCodec<CubeRoot> MAP_CODEC = UnaryProvider.codec(
// The value codec, or the codec for the generic type.
ContextFloatProviders.CODEC,
// A method that takes in the `input` and returns the constructed object.
CubeRoot::new
);
@Override
public MapCodec<CubeRoot> codec() {
return MAP_CODEC;
}
@Override
public float getFloatUnsafe(LootContext context) {
// Perform the operation through the available API methods.
return (float) Math.cbrt(this.input().value().getFloatUnsafe(context));
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.CONTEXT_FLOAT_PROVIDER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "cube_root"),
CubeRoot.MAP_CODEC
);
Finally, ContextFloatProvider and ContextIntProvider can be used outside the inlined, loot table context, for such things like data components. Given the reloadable nature, vanilla provided ResolvableFloat and ResolvableInt to hold either a constant or ResourceKey for the associated provider to resolve against. You can see examples of this in the other subsections below.
Block Transformers
BlockTransformer is a new datapack component and world datapack registry that is used to turn one block into another, such as when right-clicking with an item. This replaces AxeItem#STRIPPABLES with BlockTransformers#AXE, ShovelItem#FLATTENABLES with BlockTransformers#SHOVEL, and HoeItem#TILLABLES with BlockTransformers#HOE. As this was the last remaining difference compared to a normal Item, AxeItem, ShovelItem, and HoeItem have been removed.
BlockTransformer takes in a list of BlockTransformData, which is checked against to determine whether the transformation can apply. Each BlockTransformData takes in the BlockStateProvider holder that determines the block to place, the SoundEvent holder to play on a successful transformation, the $TransformParticle to spawn on success, a list of Directions that prevent the transformation (e.g., shovel flatenning cannot be done on the Direction#DOWN face of the block), an optional LootTable key for any items to drop on success, the $DropStrategy for where the loot should be dropped from, whether to update the newly placed block using the neighbor states (e.g. connecting a fence to other nearby fence posts), a $TransformType which is only added for fixing copper chest behavior, whether the held item should be consumed on use, and how much damage to apply to the item when used. Some of these settings are exclusive to one another and are limited in the modded context due to their implementation.
Note that the transformations are entirely controlled by the BlockStateProvider, meaning that the block transformer can transform any block into any other block, regardless of condition.
As a world datapack registry, it is highly recommended to generate the entry instead of inlining it. Additionally, for broader support, it is worthile to create a BlockStateProvider that can determine its entries using a find first approach:
// A basic block state provider that resolves using a tag.
// With this, new entries can be added to the transformer based on a tag
// rather than overriding the entire transformer.
public class FindFirstStateProvider(@Nullable Holder<BlockStateProvider> fallback, HolderSet<BlockStateProvider> providers) implements BlockStateProvider {
public static final MapCodec<FindFirstStateProvider> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
BlockStateProvider.CODEC.optionalFieldOf("fallback").forGetter(provider -> Optional.ofNullable(provider.fallback)),
RegistryCodecs.holderSet(Registries.BLOCK_STATE_PROVIDER, BlockStateProvider.DIRECT_CODEC).fieldOf("providers")
.forGetter(FindFirstStateProvider::providers)
).apply(instance, FindFirstStateProvider::new)
);
@Override
public MapCodec<FindFirstStateProvider> codec() {
return CODEC;
}
@Override
public BlockState getState(LevelAccessor level, RandomSource random, BlockPos pos) {
// Redirect to optional for convenience.
@Nullable
BlockState result = this.getOptionalState(level, random, pos);
return result != null ? result : level.getBlockState(pos);
}
@Nullable
@Override
public BlockState getOptionalState(LevelAccessor level, RandomSource random, BlockPos pos) {
return this.providers.stream()
// Get the optional state.
.map(provider -> provider.value().getOptionalState(level, random, pos))
// Filter out any null values.
.filter(Objects::nonNull)
// Get the first value that matches.
.findFirst()
// If all values returned null, evaluate fallback.
.orElseGet(
() -> this.fallback == null ? null : this.fallback.value().getOptionalState(level, random, pos)
);
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.BLOCK_STATE_PROVIDER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "find_first"),
FindFirstStateProvider.CODEC
);
As for the transformer itself:
// For some RegistrySetBuilder builder to generate the datapack entries.
public static final TagKey<BlockStateProvider> EXAMPLE_TRANSFORMER_ENTRIES = TagKey.create(
Registries.BLOCK_TRANSFORMER,
Identifier.fromNamespaceAndPath("examplemod", "transformer/example_entries")
);
// The resource key to register.
public static final ResourceKey<BlockTransformer> EXAMPLE_TRANSFORMER = ResourceKey.create(
Registries.BLOCK_TRANSFORMER,
Identifier.fromNamespaceAndPath("examplemod", "example_transformer")
);
// Add to the appropriate provider.
builder.add(Registries.BLOCK_TRANSFORMER, bootstrap -> {
bootstrap.register(
EXAMPLE_TRANSFORMER,
// Create the transformer.
new BlockTransformer(
// The list of data entries to apply.
List.of(
// Create the transformer, typically through `BlockTransformData#builder`
BlockTransformData.builder(
// The provider that returns the block to place.
new FindFirstStateProvider(
null, bootstrap.lookup(Registries.BLOCK_TRANSFORMER).getOrThrow(EXAMPLE_TRANSFORMER_ENTRIES)
)
).sound(
// The sound event to play on a successful transformation.
// If your sound event isn't already a holder, it can be wrapped
// using `Registry#wrapAsHolder`.
// Defaults to the empty sound.
BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.AMETHYST_CLUSTER_HIT)
).particle(
// The particle to show on a successful transformation.
// This must be a `$TranformParticle`:
// - NONE (No particles)
// - SCRAPE (`ParticleTypes#SCRAPE` via level event 3005)
// - WAX_ON (`ParticleTypes#WAX_ON` via level event 3003)
// - WAX_OFF (`ParticleTypes#WAX_OFF` via level event 3004)
// Defaults to NONE.
BlockTransformer.TranformParticle.NONE
).disallowedFaces(
// A list of directions that this transform data does not apply for.
// In the item use context, if a direction in this list matches the
// clicked face of a block, the transform data is skipped.
// Defaults to an empty list.
List.of()
).loot(
// A loot table of any additional items to drop on a successful
// transformation. Vanilla uses this to drop hanging roots when
// tilling rooted dirt.
// If none is present, then no additional loot drops.
// Defaults to an empty optional.
BuiltInLootTables.END_CITY_TREASURE
).dropStrategy(
// If a loot table is specified, how the items should drop on a
// successful transformation. This is ignored if no loot table
// is set.
// This must be a `$DropStrategy`:
// - CLICKED_FACE (Drops from the clicked face position)
// - FROM_MIDDLE (Drops from the middle of the block)
// Defaults to FROM_MIDDLE.
BlockTransformer.DropStrategy.CLICKED_FACE
).updateFromNeighbors(
// Whether this block should be updated by its adjacent
// neighbors via `BlockState#updateShape`. This should
// only be `false` in very particularized situations that
// are not normally encountered.
// Defaults to `true`.
true
).transformType(
// The type of transform being applied on success. This
// is currently only for handling some update differences
// for copper chests.
// This must be a `$TransformType`:
// - SINGLE_BLOCK (A regular old block)
// - COPPER_CHEST (A copper chest transformation)
// Defaults to SINGLE_BLOCK.
BlockTransformer.TransformType.SINGLE_BLOCK
).consumeOnUse(
// When `true`, the held `ItemStack` is consumed on a successful
// transformation. This is ignored if the item is not stackable.
false
).itemDamagePerUse(
// The amount of durability to take away from the item when performing
// a successful transformation. This is ignored if the item is stackable.
1
).build()
)
// ...
)
);
});
And the generated JSON:
// For some block transformer.
// In `data/examplemod/block_transformer/example_transformer.json`
// The list of data entries to apply.
[
{
// The provider that returns the block to place.
"block_state_provider": {
"type": "examplemod:find_first",
"providers": "#examplemod:transformer/example_entries"
},
// The sound event to play on a successful transformation.
// Defaults to the empty sound.
"sound": "minecraft:block.amethyst_cluster.hit",
// The particle to show on a successful transformation.
// Either:
// - none (No particles)
// - scrape (`ParticleTypes#SCRAPE` via level event 3005)
// - wax_on (`ParticleTypes#WAX_ON` via level event 3003)
// - wax_off (`ParticleTypes#WAX_OFF` via level event 3004)
// Defaults to none.
"particle": "none",
// A list of directions that this transform data does not apply for.
// In the item use context, if a direction in this list matches the
// clicked face of a block, the transform data is skipped.
// Defaults to an empty list.
"disallowed_faces": [],
// A loot table of any additional items to drop on a successful
// transformation. Vanilla uses this to drop hanging roots when
// tilling rooted dirt.
// If none is present, then no additional loot drops.
// Defaults to an empty optional.
"loot": "minecraft:chests/end_city_treasure",
// If a loot table is specified, how the items should drop on a
// successful transformation. This is ignored if no loot table
// is set.
// Either:
// - clicked_face (Drops from the clicked face position)
// - from_middle (Drops from the middle of the block)
// Defaults to from_middle.
"drop_strategy": "clicked_face",
// Whether this block should be updated by its adjacent
// neighbors via `BlockState#updateShape`. This should
// only be `false` in very particularized situations that
// are not normally encountered.
// Defaults to `true`.
"update_from_neighbors": true,
// The type of transform being applied on success. This
// is currently only for handling some update differences
// for copper chests.
// Either:
// - single_block (A regular old block)
// - copper_chest (A copper chest transformation)
// Defaults to single_block.
"transform_type": "single_block",
// When `true`, the held `ItemStack` is consumed on a successful
// transformation. This is ignored if the item is not stackable.
"consume_on_use": false,
// The amount of durability to take away from the item when performing
// a successful transformation. This is ignored if the item is stackable.
"item_damage_per_use": 1
}
// ...
]
For the item, the component can be added through Item$Properties#delayedComponent via DataComponents#BLOCK_TRANSFORMER:
// For some `Item`.
new Item(
new Item.Properties()
.delayedComponent(DataComponents.BLOCK_TRANSFORMER, context -> context.getOrThrow(EXAMPLE_TRANSFORMER))
);
Datapack Brewing Recipes
The brewing system has been converted to a Recipe for the mix and a DataComponents#BREWING_FUEL data component for the fuel, replacing PotionBrewing and ItemTags#BREWING_FUEL.
The Recipe implementation is handled by BrewingRecipe under RecipeType#BREWING. BrewingRecipe takes in a PotionIngredient for the input slots and the fuel (reagent), and outputs an ItemStackTemplate. The length of time it takes for a potion to be brewed remains fixed at twenty seconds. A PotionIngredient is an Ingredient with an optional PotionsPredicate on the DataComponents#POTION_CONTENTS. Generating the recipes is handled through BrewingRecipeBuilder, where potion mixes are handled through brewingMix and container transformers through brewingContainerTransform. Unfortunately, both of these methods of handling recipes require you to specify every possible combination. For brewing mixes, this means at least four recipes, one for each vanilla container. And as for the container transforms, its one per every potion in the bottle.
Essentially, if you do not know a potion or container exists, the recipe will no longer work. As such, the more flexible method is to create a subtype of BrewingRecipe to handle mixes and container transforms:
// The following examples are for basic potions as vanilla has
// done before in `PotionBrewing`.
// We extend `BrewingRecipe` for these to put our items within
// the relevant `RecipePropertySet`s. If we choose not to extend
// `BrewingRecipe`, we would need to patch in our recipe checks
// where the set is used.
public class BrewingMixRecipe extends BrewingRecipe {
// The serialization objects.
public static final MapCodec<BrewingMixRecipe> MIX_MAP_CODEC = RecordCodecBuilder.mapCodec(
i -> i.group(
PotionsPredicate.CODEC.fieldOf("input").forGetter(o -> o.input.potions().get()),
Ingredient.CODEC.fieldOf("reagent").forGetter(o -> o.reagent.ingredient()),
PotionContents.CODEC.fieldOf("output").forGetter(o -> o.output.components().get(DataComponentMap.EMPTY, DataComponents.POTION_CONTENTS))
)
.apply(i, BrewingMixRecipe::new)
);
public static final StreamCodec<RegistryFriendlyByteBuf, BrewingMixRecipe> MIX_STREAM_CODEC = StreamCodec.composite(
PotionsPredicate.STREAM_CODEC,
o -> o.input.potions().get(),
Ingredient.STREAM_CODEC,
o -> o.reagent.ingredient(),
PotionContents.STREAM_CODEC,
o -> o.output.components().get(DataComponentMap.EMPTY, DataComponents.POTION_CONTENTS),
BrewingMixRecipe::new
);
public static final RecipeSerializer<BrewingMixRecipe> MIX_SERIALIZER = new RecipeSerializer<>(MIX_MAP_CODEC, MIX_STREAM_CODEC);
// Take in the potion on the item, the ingredient as part of the reagent,
// and the ouputted contents.
public BrewingMixRecipe(PotionsPredicate input, Ingredient reagent, PotionContents output) {
// Provide default values for the super ingredients.
super(
new PotionIngredient(Ingredient.of(Items.POTION), Optional.of(input)),
new PotionIngredient(reagent, Optional.empty()),
new ItemStackTemplate(
Items.POTION, DataComponentPatch.builder()
.set(DataComponents.POTION_CONTENTS, output)
.build()
)
);
}
@Override
public boolean matches(BrewingInput brew) {
// Override matches to properly test the input without looking at the item.
return this.input.potions().get().matches(brew.input()) && this.reagent.test(brew.reagent());
}
@Override
public ItemStack assemble(BrewingInput brew) {
// Override assemble to copy the input stack with the new components.
ItemStack result = brew.input().copyWithCount(1);
result.applyComponents(this.output().components());
return result;
}
@Override
public RecipeSerializer<BrewingMixRecipe> getSerializer() {
// Override to set to our serializer.
return MIX_SERIALIZER;
}
}
public class BrewingContainerTransformRecipe extends BrewingRecipe {
// The serialization objects.
public static final MapCodec<BrewingContainerTransformRecipe> CONTAINER_MAP_CODEC = RecordCodecBuilder.mapCodec(
i -> i.group(
Ingredient.CODEC.fieldOf("input").forGetter(o -> o.input.ingredient()),
Ingredient.CODEC.fieldOf("reagent").forGetter(o -> o.reagent.ingredient()),
ItemStackTemplate.CODEC.fieldOf("output").forGetter(o -> o.output)
)
.apply(i, BrewingContainerTransformRecipe::new)
);
public static final StreamCodec<RegistryFriendlyByteBuf, BrewingContainerTransformRecipe> CONTAINER_STREAM_CODEC = StreamCodec.composite(
Ingredient.STREAM_CODEC,
o -> o.input.ingredient(),
Ingredient.STREAM_CODEC,
o -> o.reagent.ingredient(),
ItemStackTemplate.STREAM_CODEC,
o -> o.output,
BrewingContainerTransformRecipe::new
);
public static final RecipeSerializer<BrewingContainerTransformRecipe> CONTAINER_SERIALIZER = new RecipeSerializer<>(CONTAINER_MAP_CODEC, CONTAINER_STREAM_CODEC);
// Take in the original container, the ingredient as part of the reagent,
// and the ouputted contents.
public BrewingContainerTransformRecipe(Ingredient input, Ingredient reagent, ItemStackTemplate output) {
// Provide default values for the super ingredients.
super(
new PotionIngredient(input, Optional.empty()),
new PotionIngredient(reagent, Optional.empty()),
output
);
}
@Override
public boolean matches(BrewingInput brew) {
// Override matches to properly test the input without looking at the potions.
return this.input.ingredient().matches(brew.input()) && this.reagent.test(brew.reagent());
}
@Override
public ItemStack assemble(BrewingInput brew) {
// Override assemble to create the output stack with the input stack's components.
return this.output.apply(1, brew.input().getComponentsPatch());
}
@Override
public RecipeSerializer<BrewingContainerTransformRecipe> getSerializer() {
// Override to set to our serializer.
return CONTAINER_SERIALIZER;
}
}
// Register the serializers.
Registry.register(
BuiltInRegistries.RECIPE_SERIALIZER,
Identifier.fromNamespaceAndPath("examplemod", "mix"),
BrewingMixRecipe.MIX_SERIALIZER
);
Registry.register(
BuiltInRegistries.RECIPE_SERIALIZER,
Identifier.fromNamespaceAndPath("examplemod", "container_transform"),
BrewingContainerTransformRecipe.CONTAINER_SERIALIZER
);
Then, we can generate the recipes using a custom RecipeBuilder or directly:
// In some `RecipeProvider` subtype
@Override
protected void buildRecipes() {
// A generic mix recipe.
this.output.accept(
ResourceKey.create(
Registries.RECIPE, Identifier.fromNamespaceAndPath("examplemod", "brewing/water_to_thick")
),
new BrewingMixRecipe(
PotionsPredicate.ofPotion(Potions.WATER),
Ingreident.of(Items.GLOWSTONE_DUST),
new PotionContents(Potions.THICK)
),
null
);
// A generic container recipe.
this.output.accept(
ResourceKey.create(
Registries.RECIPE, Identifier.fromNamespaceAndPath("examplemod", "brewing/potion_to_splash_potion")
),
new BrewingContainerTransformRecipe(
Ingredient.of(Items.POTION),
Ingreident.of(Items.GUNPOWDER),
new ItemStackTemplate(Items.SPLASH_POTION)
),
null
);
}
And the generated JSONs:
// In `data/examplemod/recipe/brewing/water_to_thick.json`
{
"type": "examplemod:mix",
"input": {
"potions": "minecraft:water"
},
"reagent": "minecraft:glowstone_dust",
"output": {
"potion": "minecraft:thick"
}
}
// In `data/examplemod/recipe/brewing/potion_to_splash_potion.json`
{
"type": "examplemod:container_transform",
"input": "minecraft:potion",
"reagent": "minecraft:gunpowder",
"output": {
"id": "minecraft:splash_potion"
}
}
The fuel is handled by DataComponents#BREWING_FUEL. The associated BrewingFuel takes in a ResolvableInt for how any uses the fuel provides, and a ResolvableFloat for how much to speed up the brew time. Both resolvable values are either a constant, or a ContextIntProvider / ContextFloatProvider reference that are resolved against the LootContextParamSets#CONTAINER_PROCESS context.
Note that, for brewing stands, the brew time is calculated every tick, meaning that if the speed multiplier changes between burning fuels, the amount of time it takes to brew will also be adjusted.
The component can be added through Item$Properties#brewingFuel, or directly through Item$Properties#component. Using brewingFuel expects a reference to datapack entries.
// For some `Item`.
new Item(
new Item.Properties()
.component(DataComponents.BREWING_FUEL, new BrewingFuel(
// How many times can the fuel be used.
new ResolvableInt.Constant(600),
// A scalar of how much faster it takes to brew the input.
// A value of `1` is the normal default.
// A value less than `1` makes brewing take longer.
// A value greater than `1` makes brewing faster.
new ResolvableFloat.Cosntant(1.0f)
))
);
It is generally recommended to use datapack-registered providers. Vanilla uses minecraft:brewing/speed_default for the common speed multiplier, which is always 1. As for the fuel uses, vanilla specifies the default uses in minecraft:brewing/uses_default, which is always 20.
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register
public static final ResourceKey<ContextIntProvider> BREWING_USES_EXAMPLE = ResourceKey.create(
Registries.CONTEXT_INT_PROVIDER,
Identifier.fromNamespaceAndPath("examplemod", "brewing/uses_example")
);
builder.add(Registries.CONTEXT_INT_PROVIDER, bootstrap -> {
bootstrap.register(
BREWING_USES_EXAMPLE,
// The number of uses the fuel provides.
new ConstantValue(10)
);
});
// For some `Item`.
new Item(
new Item.Properties()
.component(DataComponents.BREWING_FUEL, new BrewingFuel(
// How many times can the fuel be used.
BREWING_USES_EXAMPLE,
// A scalar of how much faster it takes to brew the input.
// A value of `1` is the normal default.
// A value less than `1` makes brewing take longer.
// A value greater than `1` makes brewing faster.
ContextFloatProviders.BREWING_DEFAULT_SPEED_MULTIPLIER
))
);
For reference, the JSON for our ContextIntProvider would look like so:
// In data/examplemod/context_int_provider/brewing/uses_example.json
10
Cooking Fuel Component
What items can be used as fuel within furnace-like blocks are now specified by DataComponents#COOKING_FUEL, replacing FuelValues. The associated CookingFuel takes in a ResolvableInt for how any ticks the fuel should burn for, and a ResolvableFloat for how much to speed up the cook time. Both resolvable values are either a constant, or a ContextIntProvider / ContextFloatProvider reference that are resolved against the LootContextParamSets#CONTAINER_PROCESS context.
Note that, for furnace-like blocks, the cook time is calculated every tick, meaning that if the speed multiplier changes between burning fuels, the amount of time it takes to cook will also be adjusted.
The component can be added through Item$Properties#cookingFuel, or directly through Item$Properties#component. Using cookingFuel expects a reference to datapack entries.
// For some `Item`.
new Item(
new Item.Properties()
.component(DataComponents.COOKING_FUEL, new CookingFuel(
// How many ticks the fuel should burn for.
new ResolvableInt.Constant(600),
// A scalar of how much faster it takes to cook the input.
// A value of `1` is the normal default.
// A value less than `1` makes cooking take longer.
// A value greater than `1` makes cooking faster.
new ResolvableFloat.Cosntant(1.0f)
))
);
It is generally recommended to use datapack-registered providers. Vanilla uses minecraft:cooking/speed_default for the common speed multiplier, saying that the fuel cooks inputs twice as fast if within a smoker or blast furnace. As for the fuel time, vanilla typically uses a minecraft:div int provider to make the fuel burn twice as fast within a smoker or blast furnace:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register
public static final ResourceKey<ContextIntProvider> COOKING_TIME_EXAMPLE = ResourceKey.create(
Registries.CONTEXT_INT_PROVIDER,
Identifier.fromNamespaceAndPath("examplemod", "cooking/time_example")
);
builder.add(Registries.CONTEXT_INT_PROVIDER, bootstrap -> {
bootstrap.register(
COOKING_TIME_EXAMPLE,
// Divides the first value by the second value.
ContextIntProviders.div(
// The dividend, or in our case, the base number of ticks
// the fuel should burn for.
ContextIntProviders.exactly(600),
// The divisor, or in our case, whether to use fast or normal
// burn times depending on what block our fuel is within.
Holder.direct(new ConditionalValue(
// The predicate for our condition, or in our case,
// the blocks for which our fuel burns faster.
context.lookup(Registries.PREDICATE).getOrThrow(LootPredicates.FAST_FURNACE),
// The value to use if the condition returns true,
// or in our case, the fast burn divisor.
context.lookup(Registries.CONTEXT_INT_PROVIDER)
.getOrThrow(ContextIntProviders.COOKING_FAST_BURN_TIME_REDUCTION_FACTOR),
// The value to use if the condition returns false,
// or in our case, the normal burn divisor.
context.lookup(Registries.CONTEXT_INT_PROVIDER)
.getOrThrow(ContextIntProviders.COOKING_NORMAL_BURN_TIME_REDUCTION_FACTOR)
))
).value()
);
});
// For some `Item`.
new Item(
new Item.Properties()
.component(DataComponents.COOKING_FUEL, new CookingFuel(
// How many ticks the fuel should burn for.
COOKING_TIME_EXAMPLE,
// A scalar of how much faster it takes to cook the input.
// A value of `1` is the normal default.
// A value less than `1` makes cooking take longer.
// A value greater than `1` makes cooking faster.
ContextFloatProviders.COOKING_DEFAULT_SPEED_MULTIPLIER
))
);
For reference, the JSON for our ContextIntProvider would look like so:
// In data/examplemod/context_int_provider/cooking/time_example.json
{
// Divides the first value by the second value.
"type": "minecraft:div",
// The dividend, or in our case, the base number of ticks
// the fuel should burn for.
"left": 600,
// The divisor, or in our case, whether to use fast or normal
// burn times depending on what block our fuel is within.
"right": {
"type": "minecraft:conditional",
// The predicate for our condition, or in our case,
// the blocks for which our fuel burns faster.
"condition": "minecraft:block/fast_cooking",
// The value to use if the condition returns false,
// or in our case, the normal burn divisor.
"on_false": "minecraft:cooking/normal_burn_time_reduction_factor",
// The value to use if the condition returns true,
// or in our case, the fast burn divisor.
"on_true": "minecraft:cooking/fast_burn_time_reduction_factor"
}
}
Villager Food Component
Villager food is now stored as a data component via DataComponents#VILLAGER_FOOD, replacing Villager#FOOD_POINTS. The associated VillagerFood object only stores one positive int, representing the nutrition value of the food. Vanilla typically uses 1 for this value, with bread being the only item that provides 4 nutrition. For reference, villagers want more food if they have less than 12 nutrition, and are considered to have too much food if they have more than 24 nutrition.
The component can be added through Item$Properties#villagerFood, or directly through Item$Properties#component:
// For some `Item`.
new Item(
new Item.Properties()
// How much nutrition the food should give to the villager.
.villagerFood(1)
);
Compostable Copmonent
What items can be thrown in a composter are now specified by DataComponents#COMPOSTABLE, replacing ComposterBlock#COMPOSTABLES. The associated Compostable takes in a ResolvableInt for how many layers should be added when used. The ResolvableInt can either be a constant or a ContextIntProvider reference that is resolved against the LootContextParamSets#BLOCK_INTERACT context.
The component can be added through Item$Properties#compostable, or directly through Item$Properties#component. Using compostable expects a reference to a datapack ContextIntProvider entry.
// For some `Item`.
new Item(
new Item.Properties()
.component(DataComponents.COMPOSTABLE, new Compostable(
// How many layers to add to the composter.
// If the value is less than 0, no layer will be added.
// The composter level will always be clamped to between
// 0-7 inclusive.
new ResolvableInt.Constant(1)
))
);
It is generally recommended to use datapack-registered providers. Vanilla provides five providers for adding a layer to the composter: minecraft:compostable/low for a 30% chance to add a layer, minecraft:compostable/low_medium for a 50% chance, minecraft:compostable/medium for a 65% chance, minecraft:compostable/medium_high for a 85% chance, and minecraft:compostable/always_add_one for a 100% chance. However, if a composter is empty (only the vanilla Blocks#COMPOSTER), then it will always add a single layer.
// For some `Item`.
new Item(
new Item.Properties()
// How many layers to add to the composter.
// If the value is less than 0, no layer will be added.
// The composter level will always be clamped to between
// 0-7 inclusive.
.compostable(ContextIntProviders.COMPOSTABLE_ALWAYS_ADD_ONE)
);
Hiding Amongst the Mobs: A Data Component
A new data component DataComponents#MOB_VISIBILITY has been added that can affect how visible the holding or wearing entity is to other mobs. The associated MobVisibility takes in two arguments: a HolderSet containing the EntityTypes who are affected by the visbility change, and a scalar between 0-10 inclusive that determines how much the computed range of the viewing entity should be affected. For the mob visibility to be applied, it must have the DataComponents#EQUIPPABLE component with the item in the equipped slot.
As an example, an enderman has a target range of 64 blocks by default. Assuming no other modifiers, an item with a visibility of 0.5 will shrink the detection radius to 32 blocks. Likewise, a visbility of 2 will increase the detection radius to 128 blocks. However, a visibility of 0 will still have a minimum detection radius of 2 blocks, as defined within TargetingConditions.
The component can be added through Item$Properties#loweredMobVisibility, or directly through Item$Properties#delayedComponent. Using loweredMobVisibility will create a direct HolderSet with a visibility of 0.5:
// For some `Item`.
new Item(
new Item.Properties()
.delayedComponent(DataComponents.MOB_VISIBILITY, context -> new MobVisibility(
// The entities whose visibility are affected by this item.
// Can either be an entity type id, such as "minecraft:zombie",
// or a list of entity type ids, such as ["minecraft:zombie", "minecraft:skeleton", ...],
// or an entity type tag, such as "#minecraft:zombies".
// `HolderSet#direct` can be used instead of a tag lookup.
context.lookup(Registries.ENTITY_TYPE).getOrThrow(EntityTypeTags.ZOMBIES),
// The scalar that is multiplied to the mob's visibility range.
// Must be between 0-10 inclusive.
// A value less than `1` shrinks the visibility range.
// A value greater than `1` increases the visibility range.
0.1f
))
// Mob visibility only works with `DataComponents#EQUIPPABLE`.
// Applied when item is in main hand.
.equippableUnswappable(EquipmentSlot.MAINHAND)
);
Mob Spawn Settings Environment Attribute
MobSpawnSettings have been moved off the Biome and are now an EnvironmentAttribute instead using EnvironmentAttributes#NATURAL_MOB_SPAWNS. As a positional attribute, they can be defined on the DimensionType, Biome, or within a Timeline.
// Dimension type example.
{
"attributes": {
"minecraft:gameplay/natural_mob_spawns": {
// Data has not changed from previous version.
"spawn_costs": {
// ...
},
"spawns_by_category": {
// ...
}
}
}
// ...
}
// Biome example.
{
"attributes": {
"minecraft:gameplay/natural_mob_spawns": {
"argument": {
// Data has not changed from previous version.
"spawn_costs": {
// ...
},
"spawns_by_category": {
// ...
}
},
// This is the modifier to use for spawns.
// The quirks of this modifier are explained below.
"modifier": "overlay"
}
}
// ...
}
// Timeline example.
{
"tracks": {
"minecraft:gameplay/natural_mob_spawns": {
"keyframes": [
{
"ticks": 0,
"value": {
// Data has not changed from previous version.
"spawn_costs": {
// ...
},
"spawns_by_category": {
// ...
}
}
},
{
"ticks": 1000,
"value": {
// Data has not changed from previous version.
"spawn_costs": {
// ...
},
"spawns_by_category": {
// ...
}
}
}
],
// This is the modifier to use for spawns.
// The quirks of this modifier are explained below.
"modifier": "overlay"
}
}
// ...
}
When layering spawn settings, they can either be overridden via AttributeModifier$OperationId#OVERRIDE (timeline versions take precedence, followed by biome, then dimension), or overlayed via OVERLAY: a new modifier operation added in this version. As the name implies, overlay acts as a layering system, where the data is merged together. If the data uses an object that stores data with some kind of key system, then the latter layer's value will override the former.
The overlay for MobSpawnSettings works similarly, though there are a few quirks. To review, MobSpawnSettings stores two maps: one for entity spawns, where the key is the MobCategory and the value is a WeightedList containing the spawned entities; and one for the mop costs, where the key is the EntityType and the value is the MobSpawnSettings$MobSpawnCost.
Now imagine we are trying to overlay two spawn settings that look like so:
// The former spawn settings.
{
"spawns_by_category": {},
"spawn_costs": {}
}
// The latter spawn settings.
{
"spawns_by_category": {
"creature": [
{
"type": "minecraft:pig",
"count": 8,
"weight": 1
}
]
},
"spawn_costs": {}
}
First, the overlay modifier checks whether both spawns_by_category and spawn_costs are empty, like in the former settings. If so, then the other settings will be used, in this case, the latter. The same would be true if the latter was empty, then the former will be picked.
Now, let's update the settings so that neither are completely empty:
// The former spawn settings.
{
"spawns_by_category": {
"creature": [
{
"type": "minecraft:sheep",
"count": 4,
"weight": 1
}
]
},
"spawn_costs": {}
}
// The latter spawn settings.
{
"spawns_by_category": {
"creature": [
{
"type": "minecraft:pig",
"count": 8,
"weight": 1
}
]
},
"spawn_costs": {}
}
Now, the overlay modifier will check whether both settings have the same keys in spawns_by_category and spawn_costs. If they do, then the latter settings will be used. In our case, both settings specify the creature category and have no keys in spawn_costs, meaning the former is discarded and the latter is used. Meaning, our final mob settings will look like so:
// This is the latter settings.
// The former settings were discarded since they
// both defined the same mob categories and spawn costs.
{
"spawns_by_category": {
"creature": [
{
"type": "minecraft:pig",
"count": 8,
"weight": 1
}
]
},
"spawn_costs": {}
}
So, let's modify our settings one last time so that they can be merged together for the final step:
// The former spawn settings.
{
"spawns_by_category": {
"creature": [
{
"type": "minecraft:sheep",
"count": 4,
"weight": 1
}
],
"ambient": [
{
"type": "minecraft:bat",
"count": 8,
"weight": 1
}
]
},
"spawn_costs": {
"minecraft:sheep": {
"charge": 0.0001,
"energy_budget": 10000
},
"minecraft:bat": {
"charge": 0.0001,
"energy_budget": 10000
}
}
}
// The latter spawn settings.
{
"spawns_by_category": {
"creature": [
{
"type": "minecraft:pig",
"count": 8,
"weight": 1
}
]
},
"spawn_costs": {
"minecraft:pig": {
"charge": 0.0001,
"energy_budget": 10000
},
"minecraft:bat": {
"charge": 0.05,
"energy_budget": 20
},
}
}
The settings are merged together in two steps. For spawns_by_category, it loops through all available MobCategorys. If both setting specify the same category, then only the latter is used. Otherwise, it will use whatever category is not empty. As for spawn_costs, the former settings are added first, followed by the latter settings, replacing any defined in the former.
That means, for our example, it will look like so:
// The merged spawn settings.
{
"spawns_by_category": {
// Uses the creature data defined by
// the latter settings, replacing the former.
"creature": [
{
"type": "minecraft:pig",
"count": 8,
"weight": 1
}
],
// Uses the former settings data since
// the latter didn't define any ambient spawns.
"ambient": [
{
"type": "minecraft:bat",
"count": 8,
"weight": 1
}
]
},
"spawn_costs": {
// Bat costs were replaced with the latter.
"minecraft:bat": {
"charge": 0.05,
"energy_budget": 20
},
// Defined by the latter.
"minecraft:pig": {
"charge": 0.0001,
"energy_budget": 10000
},
// Defined by the former.
"minecraft:sheep": {
"charge": 0.0001,
"energy_budget": 10000
}
}
}
Note that sheeps no longer spawn, even though their costs still remain. This is a side effect of the overlay method, as it assumes that replacing any category means you intend to define what mobs spawn there altogether, rather than a partial merge.
The Death of the Unused Block Types
The block type MapCodec registry, and subsequently Block#codec, have been completely removed. As such, any codec overrides or direct MapCodecs should be deleted as well:
// For some block.
public class ExampleBlock extends Block {
- public static final MapCodec<ExampleBlock> CODEC = BlockBehaviour.simpleCodec(ExampleBlock::new);
public ExampleBlock(BlockBehaviour.Properties properties) {
super(properties);
}
- @Override
- public MapCodec<? extends Block> codec() {
- return CODEC;
- }
// ...
}
Simplifying Types to Codecs
BlockStateProvider, StructurePlacement, and PlacementModifier no longer use a wrapping object type to act as their registered instances. Now, the registries directly take in the MapCodec used for the serialization and deserialization process. As such, BlockStateProviderType, StructurePlacementType, and PlacementModifierType have been removed. Additionally, type is now renamed to codec, taking in the registered MapCodec.
// The following is an example with `PlacementModifier`s, but can roughly apply to the
// other instances as well.
public record IdentityPlacement() implements PlacementModifier {
public static final IdentityPlacement INSTANCE = new IdentityPlacement();
// The map codec used as the registry object.
public static final MapCodec<IdentityPlacement> MAP_CODEC = MapCodec.unit(INSTANCE);
// ...
// Replaces `type`
@Override
public MapCodec<IdentityPlacement> codec() {
// Return the registry object.
return MAP_CODEC;
}
}
// Register the map codec to the appropriate registry.
Registry.register(
BuiltInRegistries.PLACEMENT_MODIFIER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "identity"),
IdentityPlacement.MAP_CODEC
);
Configuring Features without ConfiguredFeatures
Feature, ConfiguredFeature, and FeatureConfiguration have been merged together into a single Feature interface, similar to most other type and dapatack registry implementations: where a MapCodec represents the statically registered type, and the Feature interface itself is the world datapack registry. As such, the registries have been renamed to reflect that fact: BuiltInRegistries#FEATURE is now FEATURE_TYPE, while Registries#CONFIGURED_FEATURE (minecraft:worldgen/configured_feature) is now FEATURE (minecraft:worldgen/feature).
The methods on Feature are either now defaulted methods or have been moved to the Feature subtype that used them (e.g. AbstractOreFeature). The three most important that remain are codec to attach the feature type to the feature; place, which now takes in the WorldGenLevel, ChunkGenerator, RandomSource, and origin BlockPos; and getSubFeatures, which returns any other features used by the current feature.
// An example feature.
public record PlaceFirstFeature(HolderSet<PlacedFeature> features) implements Feature {
// The feature type map codec to register.
public static final MapCodec<PlaceFirstFeature> CODEC = ExtraCodecs.nonEmptyHolderSet(PlacedFeature.LIST_CODEC)
.fieldOf("features").xmap(PlaceFirstFeature::new, PlaceFirstFeature::features);
@Override
public MapCodec<PlaceFirstFeature> codec() {
// Attach the feature type to the feature.
return CODEC;
}
@Override
public Stream<Holder<Feature>> getSubFeatures() {
// Return all additional potential features.
// Otherwise, this should return an empty stream.
return this.features.stream().flatMap(f -> f.value().getFeatures());
}
@Override
public boolean place(WorldGenLevel level, ChunkGenerator chunkGenerator, RandomSource random, BlockPos origin) {
// Place any blocks for the feature.
// Usually using `setBlock` or `safeSetBlock`.
// Returns `true` if the feature was placed successfully, or otherwise `false`.
// Create the placer for the feature.
FeaturePlacer placer = new FeaturePlacer(level, chunkGenerator);
for (Holder<PlacedFeature> feature : this.features) {
if (placer.place(feature.value(), random, origin)) {
return true;
}
}
return false;
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.FEATURE_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "place_first"),
PlaceFirstFeature.CODEC
);
Note the FeaturePlacer call. This is how PlacedFeatures are placed into the world and where all the placement methods like placeWithBiomeCheck now live.
The Feature can then be registered to the world datapack registry:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<Feature> EXAMPLE_FEATURE = ResourceKey.create(
Registries.FEATURE,
Identifier.fromNamespaceAndPath("examplemod", "example_feature")
);
builder.add(Registries.FEATURE, bootstrap -> {
bootstrap.register(
EXAMPLE_FEATURE,
// Our feature.
new PlaceFirstFeature(
bootstrap.lookup(Registries.FEATURE).getOrThrow(FeatureTags.CAN_SPAWN_FROM_BONE_MEAL)
)
);
});
And the generated JSON:
// For some feature.
// In `data/examplemod/worldgen/feature/example_feature.json`
{
// Our feature.
"type": "examplemod:place_first",
"features": "#minecraft:can_spawn_from_bone_meal"
}
As for the PlacedFeature, it remains the same, including the order of the PlacementModifiers; however, PlacementModifier#getPositions has been replaced by modify. modify takes the BlockPoss through a Consumer<BlockPos> instead of returning a Stream<BlockPos>:
// An example placement modifier.
public record IdentityPlacement() implements PlacementModifier {
public static final IdentityPlacement INSTANCE = new IdentityPlacement();
// The map codec used as the registry object.
public static final MapCodec<IdentityPlacement> MAP_CODEC = MapCodec.unit(INSTANCE);
@Override
public MapCodec<IdentityPlacement> codec() {
// Return the registry object.
return MAP_CODEC;
}
@Override
public void modify(PlacementContext context, RandomSource random, BlockPos origin, Consumer<BlockPos> output) {
// Like previously, the origin represents either the feature starting point or a position generated from
// a previous modifier.
// Make any modifications and pass the position to the consumer output for it to be used by the attached
// feature.
output.accept(origin);
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.PLACEMENT_MODIFIER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "identity"),
IdentityPlacement.MAP_CODEC
);
Configured Carvers without ConfiguredWorldCarver
WorldCarver, ConfiguredWorldCarver, and CarverConfiguration have been merged together into a single WorldCarver interface, similar to most other type and dapatack registry implementations: where a MapCodec represents the statically registered type, and the WorldCarver interface itself is the world datapack registry. As such, the registries have been renamed to reflect that fact: BuiltInRegistries#CARVER is now CARVER_TYPE, while Registries#CONFIGURED_CARVER (minecraft:worldgen/configured_carver) is now CARVER (minecraft:worldgen/carver).
The methods on WorldCarver are either now defaulted / static methods or have been removed. The three most important that remain are codec to attach the carver type to the carver; carver, which now takes in the WorldGenerationContext, RandomSource, chunk and source chunk ChunkPos, and the CarverOutput; and isStartChunk, which returns whether this is where the carver should start carving.
// An example carver.
public record SingleEllipsoidCarver(float probability, HeightProvider y) implements WorldCarver {
// The carver type map codec to register.
public static final MapCodec<SingleEllipsoidCarver> MAP_CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
Codec.floatRange(0.0F, 1.0F).fieldOf("probability").forGetter(SingleEllipsoidCarver::probability),
HeightProvider.CODEC.fieldOf("y").forGetter(SingleEllipsoidCarver::y),
)
.apply(instance, CanyonWorldCarver::new)
);
@Override
public MapCodec<SingleEllipsoidCarver> codec() {
// Attach the carver type to the carver.
return MAP_CODEC;
}
@Override
public boolean isStartChunk(RandomSource random) {
// Check whether this is the starting chunk for the carver.
return random.nextFloat() <= this.probability;
}
@Override
public boolean carve(WorldGenerationContext context, RandomSource random, ChunkPos chunkPos, ChunkPos sourceChunkPos, CarverOutput output) {
// Carve out any blocks.
// Usually `CarverOutput#carve` or `WorldCarver#carveEllipsoid`.
// Returns `true` if the carver was executed successfully, or otherwise `false`.
WorldCarver.carveEllipsoid(
chunkPos,
sourceChunkPos.getBlockX(random.nextInt(16)),
this.y.sample(random, context),
sourceChunkPos.getBlockZ(random.nextInt(16)),
1,
1,
output,
(xd, yd, zd, y1) -> false
);
return true;
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.CARVER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "single"),
SingleEllipsoidCarver.MAP_CODEC
);
The WorldCarver can then be registered to the world datapack registry:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<WorldCarver> EXAMPLE_CARVER = ResourceKey.create(
Registries.CARVER,
Identifier.fromNamespaceAndPath("examplemod", "example_carver")
);
builder.add(Registries.CARVER, bootstrap -> {
bootstrap.register(
EXAMPLE_CARVER,
// Our carver.
new SingleEllipsoidCarver(
0.1f, VerticalAnchor.absolute(60)
)
);
});
And the generated JSON:
// For some carver.
// In `data/examplemod/worldgen/carver/example_carver.json`
{
// Our carver.
"type": "examplemod:single",
"probability": 0.1,
"y": 60
}
More Template Rule Tests!
Three more RuleTests have been added for use in the template system: AllOfRuleTest, AnyOfRuleTest, and NotRuleTest representing AND, OR, and NOT repsectively. While these can be used individual, vanilla uses them to create an IF/ELSE statment (via RuleTest#either) to determine what blocks to replace with ores based on the current height of the feature position.
Interfacing with BlockStateProviders
BlockStateProvider is now an interface instead of an abstract class. The only change aside from changing extends to implements is that getState now takes in a LevelAccessor instead of a WorldGenLevel.
// An example block state provider.
public record AirProvider() implements BlockStateProvider {
public static final AirProvider INSTANCE = new AirProvider();
// The map codec used as the registry object.
public static final MapCodec<AirProvider> CODEC = MapCodec.unit(INSTANCE);
@Override
public BlockState getState(LevelAccessor level, RandomSource random, BlockPos pos) {
// The block to provide.
return Blocks.AIR.defaultBlockState();
}
@Override
public MapCodec<AirProvider> codec() {
// The codec used for serialization.
return CODEC;
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.BLOCK_STATE_PROVIDER_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "air"),
AirProvider.CODEC
);
Block state providers can either be inlined or referenced as a world datapack registry (via Registries#BLOCK_STATE_PROVIDER) depending on reusability:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<BlockStateProvider> EXAMPLE_PROVIDER = ResourceKey.create(
Registries.BLOCK_STATE_PROVIDER,
Identifier.fromNamespaceAndPath("examplemod", "example_provider")
);
builder.add(Registries.BLOCK_STATE_PROVIDER, bootstrap -> {
bootstrap.register(
EXAMPLE_PROVIDER,
// Our state provider.
new AirProvider()
);
});
And the generated JSON:
// For some block state provider.
// In `data/examplemod/worldgen/block_state_provider/example_provider.json`
{
// Our state provider.
"type": "examplemod:air"
}
Interfacing with StructurePlacements
StructurePlacement is now an interface instead of an abstract class to allow more flexibility for where structures can generate. The original implementation is now called AbstractSpreadingStructurePlacement, which implements StructurePlacement.
StructurePlacement inherits five methods from AbstractSpreadingStructurePlacement: codec for the registry type object used during serialization, isStructureChunk to determine if a structure can generate at the given chunk XZ, applyAdditionalChunkRestrictions for any additional restrictions that prevent the structure from generating in that chunk, getLocatePos that returns the BlockPos of the structure start when locating the structure, and locateOffset which offsets the getLocatePos. Only isStructureChunk and codec need to be implemented:
// An example structure placement.
public record InChunkStructurePlacement(ChunkPos pos) implements StructurePlacement {
// The codec for the placement type registry object.
public static final MapCodec<InChunkStructurePlacement> CODEC = ChunkPos.CODEC.fieldOf("pos")
.xmap(InChunkStructurePlacement::new, InChunkStructurePlacement::pos);
@Override
public boolean isStructureChunk(ChunkGeneratorStructureState state, int sourceX, int sourceZ) {
// Returns whether the structure can start generation in this chunk.
return this.pos.x() == sourceX && this.pos.z() == sourceZ;
}
@Override
public MapCodec<InChunkStructurePlacement> codec() {
// The codec used for serialization.
return CODEC;
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.STRUCTURE_PLACEMENT,
Identifier.fromNamespaceAndPath("examplemod", "in_chunk"),
InChunkStructurePlacement.CODEC
);
Then, the StructurePlacement can be used as part of a structure set:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<StructureSet> EXAMPLE_SET = ResourceKey.create(
Registries.STRUCTURE_SET,
Identifier.fromNamespaceAndPath("examplemod", "example_set")
);
builder.add(Registries.STRUCTURE_SET, bootstrap -> {
bootstrap.register(
EXAMPLE_SET,
new StructureSet(
List.of(/*...*/),
// Our structure placement.
new InChunkStructurePlacement(new ChunkPos(1, 1))
)
);
});
And the generated JSON:
// For some structure set.
// In `data/examplemod/worldgen/structure_set/example_set.json`
{
// Our structure placement.
"placement": {
"type": "examplemod:in_chunk",
"pos": [ 1, 1 ]
},
"structures": [
// ...
]
}
Rewriting Density Functions
DensityFunction has been split into the raw, registered values in DensityFunction, and the compiled values to sample within DensitySampler. This is similar to the material rules and conditions (previously surface rules) splitting the actual raw value with the compiled evaluator.
DensityFunction has five methods that require implementing. First is the codec representing the function type, now a standard MapCodec. Next is the range of values the function can produce, replacing minValue and maxValue. domainAxes represent a bit mask corresponding to the Direction$Axises operate within: 1 for X, 2 for Y, and 4 for Z. rewriteChildren takes in a DfRewriteRule used to rewrite the child functions, typically for inlining or simplifying slices. Finally, compileSampler creates the DensitySampler used to compute the value at a given position. DensitySampler inherits compute and fillArray as sampleValue and sampleVolume, respectively.
// An example density function
public record SineFunction(DensityFunction input) implements DensityFunction {
// The function type map codec to register.
public static final MapCodec<SineFunction> CODEC = DensityFunction.CODEC.fieldOf("input")
.xmap(SineFunction::new, SineFunction::input);
@Override
public MapCodec<SineFunction> codec() {
// Attach the function type to the function.
return CODEC;
}
@Override
public Interval range() {
// Sine function can only output [-1, 1].
return Interval.of(-1f, 1f);
}
@Override
public @DensityFunction.Axes int domainAxes() {
// Should match the axes operating upon.
// In our case, the input function's axes.
return this.input.domainAxes();
}
@Override
public DensityFunction rewriteChildren(DfRewriteRule rule) {
// Rewrite the children, and if there's a change, construct a new function.
DensityFunction input = rule.rewrite(this.input);
return input == this.input ? this : new SineFunction(input);
}
@Override
public DensitySampler compileSampler(DensityFunction.CompileContext context) {
// We can optimize by checking if the input is constant.
if (this.input instanceof ConstantFunction(float value)) {
return new ConstantFunction.Sampler(Mth.sin(value));
}
// Otherwise, we pipe the sampler to our own.
// Compile the sampler into a density sampler.
DensitySampler input = this.input.compileSampler(context);
return new SineFunction.Sampler(input);
}
// Our sampler instance.
public record Sampler(DensitySampler input) implements DensitySampler {
@Override
public void sampleVolume(SamplerContext context, DensityBuffer outputBuffer, DensityVolume volume) {
// Sample the input first.
this.input.sampleVolume(context, outputBuffer, volume);
// Then replace with the computed value.
for (int i = 0; i < outputBuffer.size(); i++) {
outputBuffer.set(i, Mth.sin(outputBuffer.get(i)));
}
}
@Override
public float sampleValue(SamplerContext context, int blockX, int blockY, int blockZ) {
// Sample the value at the given position.
return Mth.sin(this.input.sampleValue(context, blockX, blockY, blockZ));
}
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.DENSITY_FUNCTION_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "sin"),
SineFunction.CODEC
);
Then, the DensityFunction can be registered or inlined:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<DensityFunction> EXAMPLE_FUNCTION = ResourceKey.create(
Registries.DENSITY_FUNCTION,
Identifier.fromNamespaceAndPath("examplemod", "example_function")
);
builder.add(Registries.DENSITY_FUNCTION, bootstrap -> {
bootstrap.register(
EXAMPLE_FUNCTION,
// Our function.
new SineFunction(
new ConstantFunction(0)
)
);
});
And the generated JSON:
// For some function.
// In `data/examplemod/worldgen/density_function/example_function.json`
{
// Our function.
"type": "examplemod:sin",
"input": 0
}
Not a Surface, but a Material
All references to the surface system have been replaced with the word 'material' (e.g. SurfaceSystem -> MaterialSystem). Additionally, MaterialRules (once SurfaceRules) has had its inner types split into separate files in response to material rules and conditions now having their own world datapack registries. As such, BuiltInRegistries#MATERIAL_CONDITION, MATERIAL_RULE are now MATERIAL_CONDITION_TYPE, MATERIAL_RULE_TYPE.
The underlying classes themselves remain relatively the same for implementation.
SurfaceRules$RuleSource is now MaterialRule, compiled to a RuleEvaluator (previously SurfaceRules$SurfaceRule) using the MaterialRuleContext (previously SurfaceRules$Context):
public record RandomRule(List<BlockState> states) implements MaterialRule {
// The material rule type map codec to register.
public static final MapCodec<RandomRule> CODEC = ExtraCodecs.nonEmptyList(BlockState.CODEC.listOf())
.fieldOf("states").xmap(RandomRule::new, RandomRule::states);
@Override
public MapCodec<RandomRule> codec() {
// Attach the material rule type to the material rule.
return CODEC;
}
// Previously `apply`.
@Override
public RuleEvaluator compile(MaterialRuleContext context) {
// Compiles the evaulator to return a block state
// based on the passed position.
PositionalRandomFactory factory = context.getOrCreateRandomFactory(
Identifier.fromNamepsaceAndPath("examplemod", "random")
);
return (blockX, blockY, blockZ) -> {
RandomSource random = randomFactory.at(blockX, blockY, blockZ);
return states.get(random.nextInt(states.size()));
};
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.MATERIAL_RULE_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "random_rule"),
RandomRule.CODEC
);
Then, the MaterialRule can be registered or inlined:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<MaterialRule> EXAMPLE_RULE = ResourceKey.create(
Registries.MATERIAL_RULE,
Identifier.fromNamespaceAndPath("examplemod", "example_rule")
);
builder.add(Registries.MATERIAL_RULE, bootstrap -> {
bootstrap.register(
EXAMPLE_RULE,
// Our material rule.
new RandomRule(
List.of(Blocks.DIRT.defaultBlockState())
)
);
});
And the generated JSON:
// For some material rule.
// In `data/examplemod/worldgen/material_rule/example_rule.json`
{
// Our material rule.
"type": "examplemod:random_rule",
"states": [
"minecraft:dirt"
]
}
MaterialCondition (previously SurfaceRules$ConditionSource) is similar, where the condition is compiled to a ConditionEvaluator (previously SurfaceRules$Condition) using the MaterialRuleContext:
public record ProbabilityCondition(float probability) implements MaterialCondition {
// The material condition type map codec to register.
public static final MapCodec<ProbabilityCondition> CODEC = Codec.floatRange(0.0F, 1.0F)
.fieldOf("probability").xmap(
ProbabilityCondition::new, ProbabilityCondition::probability
);
@Override
public MapCodec<ProbabilityCondition> codec() {
// Attach the material condition type to the material condition.
return CODEC;
}
// Previously `apply`.
@Override
public ConditionEvaluator compile(MaterialRuleContext context) {
// Compiles the evaulator to test whether the given condition is
// valid.
RandomSource random = context.getOrCreateRandomFactory(
Identifier.fromNamepsaceAndPath("examplemod", "random")
).fromHashOf(Identifier.fromNamepsaceAndPath("examplemod", "random"));
return () -> random.nextFloat() < this.probability;
}
}
// Register the map codec.
Registry.register(
BuiltInRegistries.MATERIAL_CONDITION_TYPE,
Identifier.fromNamespaceAndPath("examplemod", "random_condition"),
ProbabilityCondition.CODEC
);
Then, the MaterialCondition can be registered or inlined:
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<MaterialCondition> EXAMPLE_CONDITION = ResourceKey.create(
Registries.MATERIAL_CONDITION,
Identifier.fromNamespaceAndPath("examplemod", "example_condition")
);
builder.add(Registries.MATERIAL_CONDITION, bootstrap -> {
bootstrap.register(
EXAMPLE_CONDITION,
// Our material condition.
new ProbabilityCondition(0.1f)
);
});
And the generated JSON:
// For some material condition.
// In `data/examplemod/worldgen/material_condition/example_condition.json`
{
// Our material condition.
"type": "examplemod:random_condition",
"probability": 0.1
}
Noisy Musical Chairs
The noise classes have been reworked into a more hierarchical structure, causing the majority of the classes to be either renamed or reimplemented. Now, all noise classes implement Noise interface, which defines the range of values, and two get methods to return a float at a given XY or XYZ coordinate. Noise has two types: GradientNoise and NoiseStack.
GradientNoise, as the name implies, generates random gradients which are then inerpolated between using their dot product. Both PerlinNoise and SimplexNoise are a type of GradientNoise. PerlinNoise also has a SmearedPerlinNoise subtype (replaces ImprovedNoise), which fudges the Y scaling.
NoiseStack, on the other hand, represents a layering of multiple different noise levels together. The original PerlinSimplexNoise impementation is best represented as a NoiseStack of SimplexNoise layers. The same applies to the original PerlinNoise as a NoiseStack of PerlinNoise layers.
Additionally, Registries#NOISE that originally took in a NormalNoise$NoiseParameters now takes in a NormalNoise. However, the backing codec just simply remaps to the newly named NormalNoise$Parameters. Still, there are a number of additions.
amplitudes was renamed to amplitude_modifiers while firstOctave was renamed to base_octave. There is also ocatve_count, which is the length of the amplitude_modifiers. base_amplitude represents the base amplitude of the noise value before the modifiers are applied. And finally, normalize, when true, normalizes the base amplitude based on the number of octaves.
// For some RegistrySetBuilder builder to generate the datapack entries.
// The resource key to register.
public static final ResourceKey<NormalNoise> EXAMPLE_NOISE = ResourceKey.create(
Registries.NOISE,
Identifier.fromNamespaceAndPath("examplemod", "example_noise")
);
builder.add(Registries.NOISE, bootstrap -> {
bootstrap.register(
EXAMPLE_NOISE,
// The normal noise.
// Computes the base amplitude from the base octave
// and amplitude modifiers.
NormalNoise.createParity(-7, 0.4, 0.5, 1.0)
);
});
And the generated JSON:
// For some noise.
// In `data/examplemod/worldgen/noise/example_noise.json`
{
// The normal noise.
// If the modifier list is all 1s, it can be excluded.
"amplitude_modifiers": [
0.4,
0.5,
1.0
],
// Computed from the base octave and amplitude modifiers.
"base_amplitude": 0.8500634887071167,
"base_octave": -7,
// The number of octaves. Matches the number of modifiers.
"octave_count": 3
}
net.minecraft.advancementsAdvancement$Builder#display->rootDisplay,Identifiercan no longer be nulldisplaymethod still exists, but no longer takes in anIdentifiersavenow takes in aBootstrapContext<Advancement>instead of aConsumer<AdvancementHolder>
AdvancementHolderLIST_STREAM_CODECis removedregister- Registers anAdvancementto the given context.
AdvancementNodeisTask- Checks whether the node has a parent.isRoot- Whether the node does not have a parent.
AdvancementProgress#serializeToNetwork,fromNetworkreplaced bySTREAM_CODECAdvancementRequirements(FriendlyByteBuf),#writereplaced bySTREAM_CODECAdvancementRewardsnow takes in aHolderSetofLootTables instead of a list of tableResourceKeys$Builder#loot,addLootTablenow takes in aHolderof aLootTableinstead of itsResourceKey
AdvancementTreeaddAllnow takes in anIterableofAdvancementHolderinstead of aCollectiontasks- Returns the child nodes.setListener,$Listenerare removedrepositionNodes- Updates the screen position of all nodes currently in the tree.
AdvancementType#STREAM_CODEC- The network codec for the type.CriterionProgress#serializeToNetwork,fromNetworkreplaced bySTREAM_CODECDisplayInfois now a recordannounceChat->announceToChatsetLocation->AdvancementNode#setLocationgetX,getY->AdvancementNode#x,y
net.minecraft.advancements.predicatesBlockPredicateMAP_CODEC- A map codec for the predicate.matchesStateis nowpublicfromprivatematchesBlockEntityis nowpublicfromprivate, no longer taking in theNbtPredicatewillMatchBlockEntity- If the predicate has NBT data present but no components.
ContextAwarePredicateclass is removed- Replaced by a
Holder<LootItemCondition>
- Replaced by a
MobEffectsPredicatenow implementsPredicate<MobEffectInstance>STREAM_CODEC,$MobEffectInstancePredicate#STREAM_CODEC,$MobEffectInstancePredicate#MAP_STREAM_CODEC- Network codecs for the predicate.
TagPredicatenow takes in aHolderSetinstead of aTagKeyis,isNotnow take in theHolderGetter- They also now have an overload that only takes in the
HolderSet
- They also now have an overload that only takes in the
net.minecraft.advancements.predicates.entityEntityPredicateADVANCEMENT_CODECis removed- All references of
ContextAwarePredicatereplaced byHolder<LootItemCondition>
net.minecraft.advancements.triggers- All references of
ContextAwarePredicatereplaced byHolder<LootItemCondition> BeeNestDestroyedTrigger$TriggerInstancenow takes in an optionalHolderSet<Block>instead of aHolder<Block>and an optionalStatePropertiesPredicatefor the block statedestroyedBeeNestnow takes in aHolderGetter<Block>, or instead aHolderSet<Block>instead of aBlock
BrewedPotionTriggertrigger,$TriggerInstance#matchesnow takes inPotionContentsinstead of aHolder<Potion>$TriggerInstance#potionis now an optionalPotionsPredicateinstead of aHolder<Potion>
EnterBlockTrigger$TriggerInstancenow takes in an optionalHolderSet<Block>instead of aHolder<Block>entersBlocknow takes in aHolderSet<Block>instead of aHolder<Block>
ItemUsedOnLocationTrigger$TriggerInstanceplacedBlock,placedBlockWithPropertiesnow take in aHolderGetter<Block>placedBlock(LootItemCondition.Builder...)->placedBlock(LootItemCondition.Builder)
LootTableTrigger$TriggerInstancenow takes in aHolderSet<LootTable>instead of aResourceKeylootTableUsedcan now either take aHolder<LootTable>orHolderSet<LootTable>instead of aResourceKey
RecipeCraftedTrigger$TriggerInstancenow takes in aHolderSet<Recipe>instead of aResourceKeycraftedItem,crafterCraftedItemnow take in aHolderSet<Recipe>instead of aResourceKey
RecipeUnlockedTriggerunlockednow takes in aHolder<Recipe>orHolderSet<Recipe>instead of aResourceKey$TriggerInstancenow takes in aHolderSet<Recipe>instead of aResourceKey
SlideDownBlockTrigger$TriggerInstancenow takes in an optionalHolderSet<Block>instead of aHolder<Block>slidesDownBlocknow takes in an optionalHolderSet<Block>instead of aBlock
- All references of
net.minecraft.client.gui.screens.advancementsAdvancementTabnow takes in theAdvancementWidget,ItemStackTemplate, titleComponent, andIdentifierbackground instead of theAdvancementNodeandDisplayInfocopyPosition- Copies the position of another tab.getRootNode->getRootAdvancement, returning theAdvancementHolderinstead of theAdvancementNodegetDisplayis removed
AdvancementWidgetis nowprivatefrompublic, no longer taking in theAdvancementTabcreateWidget- Creates a widget for the advancement node.extractHovernow takes in the screen widthattachToParentnow takes in theAdvancementTabgetAdvancement- Returns the referenced advancement.getDisplay- The display information for the advancement.
net.minecraft.client.multiplayerClientAdvancementsprogress- Returns all advancement progress.getTree->tree$Listenerno longer extendsAdvancementTree$ListeneronUpdateAdvancementProgressreplaced byonAdvancementsUpdated,onAdvancementsCleared
ClientPacketListenerpotionBrewingis removedfuelValuesis removed
net.minecraft.coreHolder#getRegisteredNameIfPresent- Returns an optional continaing the registered identifier if present.HolderGetternow extendsHolderOwnerHolderLookup$RegistryLookupno longer extendsHolderOwnerHolderOwner#canSerializeIn->canSerializeRegistryCodecs->.core.registries.codec.RegistryCodecshomogeneousList->holderSet
RegistrySetBuilderaddno longer takes in aLifecycle- It also has an overload that takes in only a
MultiRegistryBootstrap
- It also has an overload that takes in only a
buildnow takes in aHolderLookup$Providerinstead of aRegistryAccessbuildnow takes in aHolderLookup$Providerinstead of aRegistryAccessfor the context$BuildStatesplit betweeen$BuildStateand$BootstrappedRegistryState$RegistryBootstrap->SingleRegistryBootstrap$EmptyTagLookupWrapper->EmptyTagLookupWrapper, not one-to-one
net.minecraft.core.componentBlockTransformer,DataComponents#BLOCK_TRANSFORMER- A component that performs a transformation on a block when right clicked by an item.DataComponentsSWING_ANIMATIONsplit intoATTACK_ANIMATION,INTERACT_ANIMATIONMAP_COLORis removedVILLAGER_FOOD- Marks an item that can be eaten by a villager.COMPOSTABLE- Marks an item as compostable in a composter.COOKING_FUEL- Marks an item that can be burned as fuel in a furance.BREWING_FUEL- Marks an item that can be used as fuel in a brewing stand.MOB_VISIBILITY- Affects the visibility of the holder to another entity when targetting.PROVIDES_POTTERY_PATTERN- Marks the item as able to provide a deocration for a pot.SIGN_TEXT_FRONT,SIGN_TEXT_BACK- Sign block front and back text.WAXED- If a block has been waxed (set as part of the block entity like signs).CUSHION_COLOR- The color of a cushion block.
Removed- Marks a component object of having its data removed.
net.minecraft.core.component.predicatePotionsPredicatecan now specify an optional collection of effects the potion must haveSTREAM_CODEC- The network codec.potions->ofPotionsofPotion- Creates a predicate that checks against one potion.
net.minecraft.core.registries.codec.RegistryCodecs#holder- Returns a holder codec for the specified registry.net.minecraft.core.registriesBootstrapRegistry- A registry used when bootstrapping values for a datapack.BuiltInRegistriesLOOT_NUMBER_PROVIDER_TYPEsplit intoCONTEXT_FLOAT_PROVIDER_TYPE,CONTEXT_INT_PROVIDER_TYPECARVER->CARVER_TYPE, now aMapCodecFEATURE->FEATURE_TYPE, now aMapCodecSTRUCTURE_PLACEMENTis now aMapCodecinstead of aStructurePlacementTypeBLOCKSTATE_PROVIDER_TYPE->BLOCK_STATE_PROVIDER_TYPE, now aMapCodecinstead of aBlockStateProviderTypePLACEMENT_MODIFIER_TYPEis now aMapCodecinstead of aPlacementModifierTypeMATERIAL_CONDITION->MATERIAL_CONDITION_TYPEMATERIAL_RULE->MATERIAL_RULE_TYPEBLOCK_TYPEis removedDECORATED_POT_PATTERNis removed- Now a datapack registry
CONTEXT_KEY_SET- A registry containing loot context sets.NOISEis now aNormalNoiseinsetad ofNormalNoise$NoiseParameters
MultiRegistryBootstrap- A registry bootstrap for multiple registries at the same time (e.g., recipes).PatchedRegistry- A registry used when adding dynamic values from a datapack.RegistriesBLOCKSTATE_PROVIDER_TYPE->BLOCK_STATE_PROVIDER_TYPE, now aMapCodecinstead of aBlockStateProviderTypeBLOCK_TYPEis removedCARVER->CARVER_TYPE, now aMapCodecFEATURE->FEATURE_TYPE, now aMapCodecLOOT_NUMBER_PROVIDER_TYPEsplit intoCONTEXT_FLOAT_PROVIDER_TYPE,CONTEXT_INT_PROVIDER_TYPEMATERIAL_CONDITION->MATERIAL_CONDITION_TYPEMATERIAL_RULE->MATERIAL_RULE_TYPEPLACEMENT_MODIFIER_TYPEis now aMapCodecinstead of aPlacementModifierTypeSTRUCTURE_PLACEMENTis now aMapCodecinstead of aStructurePlacementTypeCONTEXT_KEY_SET- A registry containing loot context sets.BLOCK_STATE_PROVIDER- Datapack registry forBlockStateProviders.CONFIGURED_CARVER->CARVERCONFIGURED_FEATURE->FEATUREMATERIAL_CONDITION- Datapack registry forMaterialConditions.MATERIAL_RULE- Datapack registry forMaterialRules.NOISEis now aNormalNoiseinsetad ofNormalNoise$NoiseParametersBLOCK_TRANSFORMER- Datapack registry forBlockTransformers.SLOT_SOURCE- Datapack registry forSlotSourcesCONTEXT_FLOAT_PROVIDER,CONTEXT_INT_PROVIDER- Datapack registries for number providers.
net.minecraft.resourcesHolderSetCodec->.minecraft.core.registries.codec.HolderSetCodecRegistryFileCodec->.minecraft.core.registries.codec.RegistryFileCodecRegistryFixedCodec->.minecraft.core.registries.codec.RegistryFixedCodec
net.minecraft.data.advancementsAdvancementProvidernow implementsSingleRegistryBootstrapinstead ofDataProvider- The constructor only takes in a list of
AdvancementSubProvider$Factorys
- The constructor only takes in a list of
AdvancementSubProvideris now an abstractclassfrom aninterfacegenerateno longer takes in any argumentscreatePlaceholderis removed$Factory- Creates a sub provider with the given advancement registration context.
net.minecraft.data.lootBlockLootSubProvidernow takes in aLootTableSubProvider$Contextinstead of aHolderLookup$Providerregistriesreplaced byoutputenchantments,items,blocks,predicates- Common registries to query from.hasSilkTouchnow returns aHolder<LootItemCondition>instead of aLootItemCondition$BuilderhasShearsnow returns aHolder<LootItemCondition>instead of aLootItemCondition$BuildercreateSelfDropDispatchTablenow takes aHolder<LootItemCondition>instead of aLootItemCondition$Builderfor the conditioncreateSingleItemTablenow takes aHolder<ContextIntProvider>instead of aNumberProviderfor the countcreateSingleItemTableWithSilkTouchnow takes aHolder<ContextIntProvider>instead of aNumberProviderfor the count
EntityLootSubProvidernow takes in aLootTableSubProvider$Contextinstead of aHolderLookup$Providerregistriesreplaced byoutputenchantments,items,entityTypes,frogVariants,damageTypes,lootTables- Common registries to query from.createSheepDispatchPoolnow takes aColorCollection<Holder<LootTable>>instead of aResourceKeykilledByFrogno longer takes in theHolderGetterregistrykilledByFrogVariantno longer takes in theHolderGetterregistries
LootTableProvidernow implementsSingleRegistryBootstrapinstead ofDataProvider- The constructor no longer takes in the
PackOutputor registriesCompletableFuture $MissingTableProblemis removed$SubProviderEntry#providerreplaced bybootstrap, now aLootTableSubProvider$Factory
- The constructor no longer takes in the
LootTableSubProvidergeneratereplaced by$Context#accept, not one-to-onerun- Runs the sub provider.$Context- A registrar wrapper for registering loot tables.$Factory- Creates a sub provider with the given loot table registration context.
net.minecraft.data.recipesBrewingProvider- A provider for brewing recipes.BrewingRecipeBuilder- A builder for brewing mixes and container transformations.RecipeOutputnow extendsBootstrapContextAccessincludeRootAdvancementis removed
RecipeProvidernow takesBootstrapContexts for the recipe and avancements instead of aHolderLookup$ProviderandRecipeOutputregistriesis removedadvancementOutput- Registrar to register advancements.$Runneris removed
TransmuteRecipeBuilder#transmutenow has an overload that takes in aTransmuteResultfor the result
net.minecraft.data.recipes.packs.VanillaBrewingProvider- Vanilla brewing recipes.net.minecraft.data.registriesRegistriesDatapackGeneratornow takes in aStringname along with a collection ofRegistryDataLoader$RegistryDataforWorldLayer,forReloadableLayer- Registries for specific layers of the game.
RegistryPatchGenerator#createLookupsplit intocreateWorldLookup,createReloadableLookup- Original usage is
createWorldLookup
- Original usage is
TradeRebalanceRegistries#createLookupsplit intocreatePatchedWorldRegistries,createPatchedReloadable- Original usage is
createPatchedWorldRegistries
- Original usage is
VanillaRegistriesvalidateThatAllBiomeFeaturesHaveBiomeFilter(HolderLookup$Provider)is nowpublicfromprivate- Replaces the method of the same name
validateLootData- Validates registered loot tables.createLookupsplit intocreateWorldLookup,createReloadableLookup- Original usage is
createWorldLookup
- Original usage is
net.minecraft.data.tags.BlockItemTagsProvider$CombinedAppender#addTagnow has an overload that takes in a varargs ofBlockItemTagIdsnet.minecraft.data.worldgenAbandonedCampStructurePools- Structure template pools for abandoned camps.BiomeDefaultFeaturesaddDappledForestVegetation- Vegetation for dappled forest.
BlockStateProviders- Commonly used block state providers in worldgen.BootstrapContextnow extendsBootstrapContextAccessregisterno longer takes in aLifecyclelookup->BootstrapContextAccess#lookup
BootstrapContextAccess- An accessor to other registries accessable during bootstrap.Carversis now aninterfacefrom aclassNoiseRouterData->.minecraft.world.level.levelgen.NoiseRouterData
net.minecraft.data.worldgen.materialEndMaterialRules- Material rules for the end.NetherMaterialRules- Material rules for the nether.OverworldMaterialRules- Material rules for the overworld.VanillaMaterialConditions- Vanilla conditions for material placement.VanillaMaterialRules- Common material rules.
net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacketis now a record- The constructor now takes in a list of
$PositionedAdvancements instead ofAdvancementHolders $PositionedAdvancement- An advancement at a given relative screen location.
- The constructor now takes in a list of
net.minecraft.resourcesRegistryDataLoaderWORLDGEN_REGISTRIES->WORLD_REGISTRIESRELOADABLE_REGISTRIES- Registries that can reloaded while in game.
RegistryLoadTask#createRegistryInfois removedRegistryOpsowneris removed$RegistryInfois removed$RegistryInfoLookup#lookupnow returns an optionalHolderGetterinstead of a$RegistryInfo
ResourceKey#REGISTRY_STREAM_CODEC- A network codec for a registry resource key.
net.minecraft.serverMinecraftServerpotionBrewingis removedfuelValuesis removed
RegistryLayer#WORLDGEN->WORLDServerAdvancementManagerno longer implementsSimpleJsonResourceReloadListener
net.minecraft.server.packsAbstractPackResources->AbstractPackMetadataResourcesCompositePackResources->OverlayedPackResourcesFixedPathPackResources- A pack that has all resources defined on class initialization.PackMetadataResources- An interface that accesses the metadata of a pack.PackResourcesnow extendsPackMetadataResourcesgetRootResource->PackMetadataResources#getRootResourcegetMetadataSection->PackMetadataResources#getMetadataSectionlocation->PackMetadataResources#location$Filter- A predicate that checks whether a resource can be accessed.
VanillaPackResourcesno longer implementsPackResources- The constructor is now
publicfrom package-private, taking in aFixedPathPackResourcesand the list ofPackResourcesfullResources- Returns all resourcee provided.asResourcesSupplier- Constructs a resource supplier for the vanilla resources.asProvideris removedasResourceManager- Constructs a manager for accessing the vanilla client resources.
- The constructor is now
VanillaPackResourcesBuilder#pushLayer- Constructs a new pack layer with its own metadata section.
net.minecraft.server.packs.repositoryBuiltInPackSourcecreateVanillaPacknow takes in aPack$ResourcesSupplierinstead of thePackResourcesfixedResourcesis removed
PackopenMetadata-> Returns the pack metadata.$ResourcesSupplieropenPrimary->openMetadataopenFull->openResources, now returning a stream ofPackResources
net.minecraft.server.packs.resourcesFallbackResourceManagerfallbacksin nowprivatefromprotectedpush,pushFilterOnlynow take in aPackResources$Filterinstead of anIdentifierpredicate
Resource#readAllAsString- Reads the resource data into a string.ResourceManagerlistResources,listResourceStacksnow tak in aResourceManager$Selectorinstead of anIdentifierpredicate$Selector- A predicate that checks whether a resource can be accessed.
SimpleJsonResourceReloadListenerSimpleJsonResourceReloadListener(HolderLookup$Provider, Codec, ResourceKey)is removedscanDirectoryis removed
net.minecraft.utilBoundedFloatFunction#minValue,maxValuemerged intorangeCubicSplinemapCoordinatesnow takes in a function that returns aBoundedFloatfunctioninstead of aUnaryOperatorforEachCoordinate- Loops through all coordinates in the spline.minValue,maxValuemerged intorange$Multipointno longer takes in the main and maxfloatvalues
Interval- Represents a range between two values.
net.minecraft.util.context.ContextMapis now finalEMPTY- An empty context map.builder- Creates a builder for a context map.getOptional->get$Builderconstructor is nowprivatefrompublicwithOptionalParameter->setwithParameter,getParameterare removedgetOptionalParameter->getcreate->buildAndValidatebuild- Creates the context map without validation against some key set.
net.minecraft.util.valueproviders.VeryBiasedToBottomInt- An int provider that biases towards the minimum value by running the random call three times.net.minecraft.world.attributeAttributeRange#UNIT_FLOAT_EPSILON- Represents a number between 0 and 1 with an episilon factor included.AttributeTypenow takes in aToIntFunctionto convert the attribute value to an integertoInt- Converts the attribute value to an integer.
AttributeTypesRGB_COLORis now aVector3fcfrom anIntegerARGB_COLORis now aVector4fcfrom anIntegerMOB_SPAWN_SETTINGS- Settings for mob spawning in an environment.
BedRulenow splits the explodesbooleaninto one for destroying on use, and one for destroying on leaving the bedEnvironmentAttribute#isFullResolutionBiomes,$Builder#fullResolutionBiomes- When true, gets the biome throughBiomeManager#getBiomeinstead ofBiomeManager#getNoiseBiomeAtPositionEnvironmentAttributesSTRAW_BED_RULE- A rule for what happens with straw beds.NATURAL_MOB_SPAWNS- A rule for how mobs should spawn.CREATURE_WORLD_GEN_SPAWN_PROBABILITY- A rule for the likelihood creatures should spawn for each chunk on generation.
EnvironmentAttributeSystem$BuilderaddStaticLayers- Adds the biome and dimension layers to the attribute system.addDynamicLayers- Adds the weather and timeline layers to the attribute system.
LerpFunctionofColorVec3,ofColorVec4- SRGB lerp functions.ofListCrossFade- Cross fades the element values in a list by merging both lists toegether, setting the front elements with one minus the alpha value, and the to as the alpha value.$AlphaScaler- A function that converts an item based on some alphafloat.
net.minecraft.world.attribute.modifierAttributeModifierMOB_SPAWN_SETTINGS_LIBRARY- Operations for mob spawn settings (only overlay).listLibrary- Operations for a list of elements (only append).$OperationIdOVERLAY- Merges the elements together, having the latter's contents take priority over the former.APPEND- Appends the elements into a single collective.
ColorModifiernow uses an arbitrary subject instead of anInteger- All constant modifiers are now split into
*_RBGor*_ARGB, using aVector3fcorVector4fc, repsectively. $ArgbModifiernow uses an arbitrary subject instead of anInteger$BlendToGray#lerp- Linearly interpolates between two gray blends based on an alpha.$RgbModifiernow uses an arbitrary subject instead of anInteger
- All constant modifiers are now split into
ListModifier- A modifier that joins two lists together.MobSpawnSettingsModifier- Merges the spawn settings together, having the latter's contents take priority over the former.
net.minecraft.world.clockClockInstance- An interfaces that defines a clock's data.ClockManager#getTotalTicks->getInstance, now returning aClockInstanceinstead of alongServerClockManagermoveToTimeMarkernow returns a$MoveResultinstead of aboolean$MoveResult- The result of moving a time marker.$ClockInstance->$ServerClockInstance, now implementingClockInstance,publicfromprivate
net.minecraft.world.food.VillagerFood- A data component representing that the item is food for a villager, providing a certain amount of nutrition.net.minecraf.tworld.inventory.BrewingStandMenugetTotalFuel- The amount of fuel remaining in the brewing stand.getTotalBrewingTicks- How long it takes for the brewing stand to finish brewing.$PotionSlotnow takes in aRecipeAccessmayPlaceItemis removed
net.minecraft.world.itemAxeItemclass is removedHoeItemclass is removedInstrumentnow takes in anintfor how much durability to remove when usedInstrumentsGOAT_HORN_INSTRUMENT_DAMAGE- How much damage a goat horn takes when used.registernow takes in anintfor how much durability to remove when used
Item$PropertiesvillagerFood- Adds theDataComponents#VILLAGER_FOODcomponent, marking that a villager can eat this item.potPattern- Adds theDataComponents#PROVIDES_POTTERY_PATTERNcomponent, marking that the item displays a pattern on a decorated pot.signText- Adds theDataComponents#SIGN_TEXT_*components, marking that the item has text to display on its front and/or back.cookingFuel- Adds theDataComponents#COOKING_FUELcomponent, marking that the item can be used as fuel in a furnace.brewingFuel- Adds theDataComponents#BREWING_FUELcomponent, marking that the item can be used as fuel in a brewing stand.compostable- Adds theDataComponents#COMPOSTABLEcomponent, marking that the item can be put in a composter.loweredMobVisibility- Adds theDataComponents#MOB_VISIBILITYcomponent, marking that the item can decrease range a mob can detect the holder from.
ShovelItemclass is removedSignItemclass is removed
net.minecraft.world.item.alchemyPotionBrewingreplaced byBrewingRecipeBuilderPotionContentsisnow has an overload that takes in theTagKeyinstead of theHolderisPotionWithoutCustomEffects- Returns whether the brew is a registered potion with no additional mob effects.
net.minecraft.world.item.componentBlockTransformers- All vanilla block transformers.BrewingFuel- A data component that marks the item can be used as fuel in a brewing stand.BundleContentsnow implementsContainerComponent$Mutablenow extendsGrowableMutableContainer- The constructor no longer takes in anything
ChargedProjectilesnow implementsContainerComponent$Mutable- A mutable version of the container component.
Compostable- A data component that marks the item can be put in a composter.ContainerComponent- An interface which defines a component that represents a backing container.CookingFuel- A data component that marks the item can be used as fuel in a furnace.GrowableMutableContainer- A mutable container that can grow in size.ItemContainerContentsnow implementsContainerComponentMAX_SIZEis nowpublicfromprivate$Mutable- A mutable version of the container component.
MapItemColorrecord is removedMobVisibility- A data component that marks the item can decrease range a mob can detect the holder from.SimpleMutableContainer- A basic mutable container backed by a list of stacks.TooltipProvider$Getter- Gets aTooltipProviderfrom some object, usually a data component.TypedEntityData#loadIntonow has an overload that takes in theSpawnDataand theDefaultedRegistry
net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffectnow takes in abooleanof whether the particles should be placed directionally towards the teleport target locationnet.minecraft.world.item.craftingAbstractCookingRecipe#cookingMapCodecno longer takes in theintdefault timeBrewingInput- ARecipeInputthat represents the input to a brewing recipe.BrewingRecipe- A recipe that takes two potion ingredients and transmutes them into an item stack.Ingredient#getSingleItem- Returns the backing item if there is only one valid value, otherwise an empty optional.MapExtendingRecipenow takes in aTransmuteResultinstead of anItemStackTemplatePotionIngredient- An ingredient that contains somePotionsPredicate.RecipeCODEC->DIRECT_CODECCODECnow represents the holderRecipe
LIST_CODEC- Codec for a set of recipes.
RecipeManagerno longer extendsSimplePreparableReloadListenergetLearnableRecipes- Returns all recipes that can be seen in a recipe book (non-special recipes).fromJsonis removed
RecipeMap#createnow takes in aHolderLookupfor the recipe rather than anIterableRecipePropertySetBREWING_INPUTS- Inputs to a brewing stand (potions).BREWING_REAGENTS- Catalysts to the brewing stand inputs (blaze powder).
TransmuteRecipenow takes in aTransmuteResultinstead of anItemStackTemplateTransmuteResult- AnItemStackTemplatethat can either specify a new item to transmute to, or use the input item.
net.minecraft.world.item.crafting.displaySlotDisplay$TagSlotDisplaynow takes in aHolderSetinstead of aTagKeySlotDisplayContextFUEL_VALUESis removedREGISTRIESnow uses aRegistryAccessgeneric instead of aHolderLookup$Provider
net.minecraft.world.item.enchantmentConditionalEffectnow takes in a holderLootItemConditioninstead of the raw condition for the requirementsTargetedConditionalEffectnow takes in a holderLootItemConditioninstead of the raw condition for the requirements
net.minecraft.world.item.enchantment.effectsReplaceBlocknow takes in a holderBlockStateProviderinstead of the raw provider for the block stateReplaceDisknow takes in a holderBlockStateProviderinstead of the raw provider for the block state
net.minecraft.world.item.slotCompositeSlotSourcenow takes in aHolderSetinstead of aListcreateCodec,createInlineCodecnow takes in a function with aHolderSetinput instead of aList
CountingModifier- A consumer that modifies theItemStack, keeping track of how many was updated.RangeSlotSource#slotRange- Creates a slot source from a range of slots in a container.SlotCollectionsize- The size of the collection.replaceSlotItems- Replaces the selected slots with the items in the provider.modifySlots- Modifies the selected slots using the given consumer.
SlotSelector- Selects slots based on the providedItemStack.SlotSourcesCODEC->DIRECT_CODECCODECnow represents the holderSlotSource
LIST_CODEC- Codec for a set of slot sources.group->CompositeSlotSource#group, nowprivatefrompublic
TransformedSlotSourcenow takes in a holderSlotSourceinstead of the raw sourcecommonFieldsnow returns aP1that transforms into a holderSlotSourceinstead of the raw source
net.minecraft.world.item.tradingTradeCostnow takes in a holderContextIntProviderinstead of the rawNumberProviderfor the countTradeSetis now a record- The constructor now takes in a holder
ContextIntProviderinstead of the rawNumberProviderfor the amount
- The constructor now takes in a holder
VillagerTradenow takes in holderLootItemConditions instead of the raw conditions, holderContextIntProviders instead ofNumberProviders for the max use and xp, and a holderContextFloatProviderinstead of aNumberProviderfor the reputation discount- The other constructors are replaced by
builder builder,$Builder- A builder for creating a villager trade.
- The other constructors are replaced by
net.minecraft.world.level.LevelpotionBrewingis removedfuelValuesis removed
net.minecraft.world.level.biomeBiomeno longer takes in theMobSpawnSettingsFROZEN_TEMPERATURE_NOISEis nowpublicfromprivate, returning aNoiseinstead ofPerlinSimplexNoiseBIOME_INFO_NOISEis nowNoiseinstead ofPerlinSimplexNoisegetMobSettingsreplaced byEnvironmentAttributes#NATURAL_MOB_SPAWNS
BiomeManagernow takes in aBiomeResolverinstead of a$NoiseBiomeSourcegetBiomenow hsa an overload that takes in the XYZintcoordinates$NoiseBiomeSourceis removed, typically replaced byBiomeResolver
BiomeResolver#getNoiseBiomeno longer takes in theClimate$SamplerBiomeSourceno longer implementsBiomeResolvergetBiomesWithin->BiomeResolver#getBiomesWithin, no longer taking in theClimate$SamplerfindClosestBiome3dnow takes in aRandomStateinstead of theClimate$SamplerfindBiomeHorizontalnow takes in aRandomStateinstead of theClimate$SamplercreateUncachedResolver,createCachingResolver,createResolver,createResolverForChunk- Handles creating theBiomesResolverdepending on context.
CheckerboardColumnBiomeSourcenow implementsBiomeResolverClimateemptyis removedfindSpawnPositionis removed$Parameter#distance(Climate$Parameter)is removed$ParameterList#rebuildWithChildrenPerNode- Creates a new parameter list with a given number of children in the per node in the index tree.$ParameterPoint#fitnessis nowpublicfromprivate$RTree#createnow has an overload that takes in the number of children per node in the tree$Samplernow takes inDensitySampler$Bounds instead ofDensityFunctions, no longer taking in the list of$ParameterPoints for the spawn targetsfindSpawnPositionis removed
$SpawnFinder->NoiseSpawnFinder, not one-to-one
FixedBiomeSourcenow implementsBiomeResolverMobSpawnSettingsno longer takes in thefloatcreature generation probabilityDEFAULT_CREATURE_WORLD_GEN_SPAWN_PROBABILITYis nowpublicfromprivateNO_SPAWNS- Mobs do not spawn in any category.CODECis now aCodecinstead of aMapCodecgetCreatureProbabilityreplaced byEnvironmentAttributes#CREATURE_WORLD_GEN_SPAWN_PROBABILITYgetMobs->getMobsToSpawngetMobsInCategory- Gets the spawn settings for the given category.definedCategories- The defined categories in the settings.allSpawnCosts- A map of entity type to spawn cost.$BuilderaddSpawnnow has overloads that take in theEntityType, anintweight, some min and max count, and optionally theMobCategoryaddAllSpawns- Adds all spawns to the given category.noSpawns- Spawns nothing for the given category.dontOverride- Removes the spawn entries for the given category.addMobCharge->addMobSpawnCostaddAllCosts- Adds all spawns costs.creatureGenerationProbabilityreplaced byEnvironmentAttributes#CREATURE_WORLD_GEN_SPAWN_PROBABILITY
$SpawnerDatanow takes in anIntProviderinstead of a min and maxintfor the count
OverworldBiomeBuilder#spawnTargetnow takes in anOverworldFunctionSetand a holderDensityFunctionfor the weirdness, returning a list ofSpawnTargetPoints instead ofClimate$ParameterPoints
net.minecraft.word.level.block*Block#CODECconstants are removedAbstractBedBlock- An abstract representaiton of a bed.BedBlocknow extendsAbstractBedBlockPART->AbstractBedBlock#PARTOCCUPIED->AbstractBedBlock#OCCUPIEDgetConnectedDirection->AbstractBedBlock#getConnectedDirectiongetBlockType->AbstractBedBlock#getBlockTypefindStandUpPosition->AbstractBedBlock#findStandUpPosition
BlockdropFromBlockInteractLootTableis nowpublicfromprivate, taking in the interactedBlockPosplayerDestroynow takes in aServerLevelandServerPlayerinstead of aLevelandPlayerbounceOn- Runs when an entity's vertical resitution after moving is greater than 0, typically due an entity's or the hit block's bounciness.getFallDistanceReduction- Returns how much the block reduces fall distance by, where 0 is no reduction, and 1 is 100% reduction.spawnDestroyParticlesno longer takes in thePlayerspawnDestroyByEntityParticlesreplaces thePlayerversion by taking in a nullableEntity
BlockTypesclass is removedBonemealBlock#isValidBonemealTarget,isBonemealSuccess,performBonemealnow takes in theBonemealSourceBonemealSource- The source who bonemealed the targetted block.BushBlocknow has an overload that takes in the block shape height.DEFAULT_SHAPE_HEIGHT- The default max Y for the block shape.
Campfire#dowse->douseComposterBlock#bootstrapreplaced byDataComponents#COMPOSTABLEDirtPathBlock->PathBlock, not one-to-oneDragonEggBlock#HORIZONTAL_TELEPORT_RADIUS,VERTICAL_TELEPORT_RADIUS- The teleport radius on egg right click.FallingParticlesLeavesBlock- An abstract leaves block that spawn falling particles.FarmlandBlocknow takes in the baseBlockit was created fromturnToDirt->turnToBaseBlock, now non-static
FlowerBedBlocknow takes in the block shape heightFlowerBlock#EFFECTS_FIELDis removedLeavesBlockis no longer abstract- The constructor now takes in an
AmbientLeavesBlockSoundPlayer leafParticleChance->FallingParticlesLeavesBlock#leafParticleChancespawnFallingLeavesParticle->FallingParticlesLeavesBlock#spawnFallingLeavesParticle
- The constructor now takes in an
RedStoneWireBlock->RedstoneWireBlockSaplingBlockBRIGHTNESS_FOR_SAPLING_GROWTH- The amount of light required for the sapling to grow.TICK_CHANCE_FOR_SAPLING_GROWTH- The chance for a sapling to grow when randomly ticked.
SculkBlock#GROWTH_INHIBITOR_RANGE- The range that skulk blocks can spread within, provided there are at most two inhibitors.ShelfMushroomBlock- The block for a shelf mushroom.StrawBedBlock- The block for a straw bed.TintedParticleLeavesBlocknow extendsFallingParticlesLeavesBlockTntBlock#prime(Level, BlockPos, LivingEntity)is nowpublicfromprivate, now taking in theItemStackprimerUntintedParticleLeavesBlocknow extendsFallingParticlesLeavesBlock
net.minecraft.world.level.block.entityAbstractFurnaceBlockEntitygetBurnDurationnow takes in theServerLevelinstead of theFuelValuesgetSpeedMultiplier- A scalar of how much faster it causes the input to be cooked.
BaseContainerBlockEntity#getLootContext- The base context for getting loot from a container.BrewingStandBlockEntityFUEL_USESreplaced byBrewingFuel#usesDATA_TOTAL_*- Identifiers for the data slots.BREWING_TIME_SECONDS- The default amount of time it takes to brew.getUses- How many times can the fuel be used.getSpeedMultiplier- A scalar of how much faster it causes the input to be brewed.serverTicknow takes in theServerLevelinstead of theLevel
DecoratedPotPattern#CODEC- A serialization codec.DecoratedPotPatternsCODEC,STREAM_CODEC- Codecs for datapack entries.itemToPatternMappingsreplaced bybootstrap
FuelValuesclass is removed, replaced byDataComponents#COOKING_FUELPotDecorationsnow takes in optionalItemStackTemplates instead ofItemsallBrick- Create a decoration of all bricks.
net.minecraft.world.level.block.grower.TreeGrowernow takes inWeightedLists of the trees, mega trees, and flower trees to spawn, instead of optionals of each specific tree type; and theResourceKeyof the shortest tree type instead of afloatfor the secondary chancecanGrow- If the tree can grow in the given location.
net.minecraft.world.level.block.stateBlockBehaviorfallDistanceReduction- How much the block reduces fall distance by, where 0 is no reduction, and 1 is 100% reduction.codec,propertiesCodec,simpleCodecare removedshowAsInteractableInSpectatorMode- Whether the block is shown as able to be interacted with in spectator mode.shouldRedstoneWireConnectTo- If redstone wire from a given direction is able to connect to this block.$BlockStateBaseblocksMotionis removedshouldRedstoneWireConnectTo- If redstone wire from a given direction is able to connect to this block.showAsInteractableInSpectatorMode- Whether the block is shown as able to be interacted with in spectator mode.isLightPermeable- Whether light can permeate through this block.isViewBlockingnow takes in theAABBnear plane boxwithPropertiesOf,copyProperty- Constructs aBlockStatewith the associated properties.
$PropertiesCODECis removedfallDistanceReduction- How much the block reduces fall distance by, where 0 is no reduction, and 1 is 100% reduction.isViewBlockingnow takes in a$StateArgumentsPredicate<AABB>instead of a$StatePredicate
BlockState#CODEC->FULL_CODECCODECnow is able to serialize theBlockStateas either a simpleBlockor theBlockStatewith its properties
net.minecraft.world.level.chunkCarverOutput- An interface that defines the basic carver functions, along with the min and max Y to carve between.CarvingMasknow implementsCarverOutput- The constructor now takes in the min and max Y
ints instead of the height and min Y setAdditionalMaskis removedset->CarverOutput#carveget,streamreplaced byvisit, not one-to-onetoArrayis removedisEmpty- Whether the mask is empty.$Mask->$Filter$Visitor- A consumer for visiting a column defined by the carver.
- The constructor now takes in the min and max Y
ChunkAccessnoiseChunkis removedincrementInhabitedTimeno longer takes in thelongdeltagetOrCreateNoiseChunkis removedfillBiomesFromNoiseno longer takes in theClimate$SamplerhasAnyStructureReferencesis removed
ChunkGeneratorgetOrigin- Returns the origin position.applyCarversis removed- Original usage in
NoiseBasedChunkGenerator#generateCarvers
- Original usage in
decorateBiomeResolver- Wraps around the original resolver to determine how biomes are placed.buildSurfaceis removed- Original usage in
NoiseBasedChunkGenerator#buildSurface
- Original usage in
getMobsAtnow takes in aLevelinstead of theBiomeholderfillFromNoise->buildTerrainnow taking in theBiomeManager,WorldGenRegion, and set of possible holderBiomesaddDebugScreenInfonow takes in theSamplerContext
ChunkGeneratorStructureStatecreateForFlat,createForNormalnow takes in the originChunkPosgetDimensionOrigin- Return the origin position.
LevelChunk#replaceWithPacketDatanow takes in the chunk XZints and theClientboundLevelChunkPacketDatainstead of the raw buffer, map, and consumerLevelChunkSection#fillBiomesFromNoiseno longer takes in theClimate$SamplerProtoChunk#getCarvingMask,getOrCreateCarvingMask,setCarvingMaskare removed
net.minecraft.world.level.chunk.stateChunkStatus#NOISE,SURFACE,CARVERSmerged intoTERRAINCARVERSis also used inBIOMES
ChunkStatusTasksgenerateNoise,generateSurface,generateCarversmerged intobuildTerraingenerateCarversalso used ingenerateBiomes
net.minecraft.world.level.levelgenAquifercreateis removedcomputeSubstancenow takes in the XYZ coordinateints instead of aDensityFunction$FunctionContext$Config#exclusion- A density value that determines what should not be part of the aquifer.
Beardifiernow implementsDensitySamplerinstead ofDensityFunctions$BeardifierOrMarkerDensityconstants are nowfloats instead ofdoublesDensityFunction->.densityfunction.DensityFunctionDensityFunctionhas been split intoDensityFunctionandDensitySamplerREFERENCE_CODEC- A codec for the holder wrappedDensityFunctionAXIS_*- Flags that indicate the axes that the density functions are operated on.NO_AXES- Operates on no axes.ALL_AXES- Operates on all axes.axesFrom- Converts aDirection$Axisto anintflag.compute->DensitySampler#sampleValue, not one-to-onefillArray->DensitySampler#sampleVolume, not one-to-onemapChildren,mapAllreplaced byrewriteChildrencompileSampler- Creates the sampler for the function given the context.minValue,maxValuemerged intorangedomainAxes- The axes the density function operates upon.codecis now aMapCodecfrom aKeyDispatchKeyCodecclampnow takes infloats instead ofdoublesinvert->negatelog- Takes the natural logarithm of the sampled value.sign- Returns the sign of the sampled value (1 positive, -1 negative, 0 zero).add- Adds the argument to the sampled value.sub- Subtracts the argument from the sampled value.mul- Multiplies the argument to the sampled value.div- Divides the sampled value by the argument.pow- Raises the sampled value to the argument.$Axes- An annotation that marks anintas an axis flag to which the density functions operate upon.$ContextProvideris removed$FunctionContextis removed, likely replaced byMaterialRuleContext$NoiseHolderlikely removed, usingHolder<NormalNoise>instead$SimpleFunctionis removed$SinglePointContextis removed$Visitoris removed, like replaced byDfRewriteRule$CompileContext- The context to help compile a function into aDensitySampler.
DensityFunctions->.densityfunction.DensityFunctionsNOISE_VALUE_CODECnowpublicfromprivate,floatinstead of adoublesqrt- Takes the square root of the sampled value.negate- Negates the sampled value.log- Takes the natural logarithm of the sampled value.sign- Returns the sign of the sampled value (1 positive, -1 negative, 0 zero).interpolatednow takes in theintcell sizes for the XZ and Y directionsflatCache,cache2d,cacheOnces,cacheAllInCellreplaced bycache, not one-to-oneshiftA,shiftB,shiftnow take a holder-wrappedNormalNoiseinstead ofNormalNoise$NoiseParametersendIslands->endOuterIslands, no longer taking in thelongseeddistanceToPoint- Determines the distance to the provided point using the specified metric.sub- Subtracts the argument from the sampled value.div- Divides the sampled value by the argument.pow- Raises the sampled value to the argument.sliceY- Samples the input along the Y axis with the fixed coordinate.slice- Samples the input along the given axis with the fixed coordinate.gradient- Samples using a gradient along the specified axis using the specificTilingModeoutside the specified range.round- Rounds the sampled value to the nearestint, calculated by the multiple if specified.floor- Floors the sampled value, calculated by the multiple if specified.ceil- Ceils the sampled value to the nearestint, calculated by the multiple if specified.truncate- Truncates the sampled value in the direct closest to 0, calculated by the multiple if specified.remap- Remaps the input function from the specified coordinate range to the new coordinate range.clampedMap- Remaps the input function from the specified coordinate range to the new coordinate range, where the input is clamped to the original range.mapdepending on$Mapped$Type:ABS->absSQUARE->squareCUBE->cubeHALF_NEGATIVE->halfNegativeQUARTER_NEGATIVE->quarterNegativeINVERT->reciprocalSQUEEZE->squeeze
$Ap2replaced byBinaryFunction$BeardifierMarker,$BeardifierOrMarkerreplaced bybeardifier,SimpleDensityFunction#BEARDIFIER$BlendAlphareplaced bySimpleDensityFunction#BLEND_ALPHA$BlendOffsetreplaced bySimpleDensityFunction#BLEND_OFFSET$Clampreplaced byclamp,ClampFunction$Constantreplaced byConstantFunction$EndIslandDensityFunctionreplaced byEndIslandFunction$FindTopSurfacereplaced byFindTopSurfaceFunction$IntervalSelectreplaced byIntervalSelectFunction$Mappedreplaced byUnaryFunction$Marker,$MarkerOrMarkedreplaced depending on$Marker$Type:Interpolated->InterpolatedFunctionFlatCache,Cache2D,CacheOnce,CacheAllInCellmerged intoCacheFunction,DensityFunctionCompiler#reuseOrPrepareCacheBlendDensity->blendDensity,BlendDensityFunction
$MulOrAddreplaced byBinaryFunction$Noisereplaced byNoiseFunction$RangeChoicereplaced byRangeChoiceFunction$Shiftreplaced byShiftNoiseFunction$Shift$ShiftAreplaced byShiftNoiseFunction$ShiftA$ShiftBreplaced byShiftNoiseFunction$ShiftB$ShiftNoisereplaced byShiftNoiseFunction$ShiftedNoisereplaced byNoiseFunction$Splinereplaced bySplineFunction$TwoArgumentSimpleFunctionreplaced byBinaryFunction$YClampedGradientreplaced byGradientFunction
GeodeBlockSettingsnow takes in holders for theBlockStateProviders instead of the raw valuesNoiseBasedChunkGeneratorgetInterpolatedNoiseValueis removedbuildSurfaceis nowprivatefrompublicapplyCarvers->generateCarvers, nowprivatefrompublic
NoiseChunkno longer implements theDensityFunction$FunctionContext,$ContextProviderforChunkis removed- The constructor no longer takes in the
intcell XZ count, minimumintchunk XZ positions,NoiseSettings; and takes in theBeardifierinstead of theDensityFunctions$BeardificerOrMarker, and theDensityVolume cachedClimateSamplerreplaced bycachingSamplers,NoiseRouter#createClimateSampler; not one-to-onegetInterpolatedState,getInterpolatedDensity,stopInterpolationare removedmaxPreliminarySurfaceLevel,preliminarySurfaceLevelare removedinitializeForFirstCellX,advanceCellX,selectCellYZ,updateForY,updateForX,updateForZare removedforIndexis removedswapSlicesis removedcellWidth,cellHeightare removedwrapis removedvolume- The volume being operated upon.
NoiseGeneratorSettingssurfaceRule->materialRule, now aHolder<MaterialRule>instead of aSurfaceRules$RuleSourcespawnTargetis now a list ofSpawnTargetPoints instead ofClimate$ParameterPointsaquifersEnabledreplaced byaquifersoreVeinsEnabledmerged intomaterialRuledebugFunctions,$DebugFunctionEntry,$DebugFunctions- Functions to display debug information about the noise functions.isAquifersEnabled,oreVeinsEnabledare removed
NoiseRouterhas been split intoNoiseRouterandAquifer$ConfigbarrierNoise->Aquifer$Config#barrierNoisefluidLevelFloodednessNoise->Aquifer$Config#fluidLevelFloodednessNoisefluidLevelSpreadNoise->Aquifer$Config#fluidLevelSpreadNoiselavaNoise->Aquifer$Config#lavaNoisepreliminarySurfaceLevelsplit intochunkSurfaceLevel, andAquifer$Config#surfaceLevelveinTogglereplaced byOreVeinRule#density, not one-to-oneveinRidgedmerged intoOreVeinRule#density, not one-to-oneveinGapreplaced byOreVeinRule#fillerGap, not one-to-onemapAllis removed
NoiseRouterDataCONTINENTS,EROSION,OFFSET,FACTOR,JAGGEDNESS,DEPTHmerged intoOVERWORLD_FUNCTIONSAMPLIFIED_OVERWORLD_FUNCTIONS- Functions for amplified world generation.LARGE_OVERWORLD_FUNCTIONS- Functions for world generation with large biomes.ORE_VEIN_*- Functions for ore vein settingsbootstrapno longer returns anythinggetFunctionis nowpublicfromprivatepeaksAndValleysis nowpublicfromprivateoverworldnow takes in theOverworldFunctionSetinstead of theNormalNoise$NoiseParametersandbooleanworld typesoverworldAquifers- The aquifer config for the overworld.floatingIslandsnow takes in a getter ofNormalNoiseinstead ofNormalNoise$NoiseParameters$QuantizedSpaghettiRarity#wrapRarity2d,wrapRarity3dnow take in a holder-wrappedNormalNoiseinstead ofNormalNoise$NoiseParameters
Noises- Constants are now resource keys of
NormalNoiseinstead ofNormalNoise$NoiseParameters instantiateno returns aNoiseinstead ofNormalNoise
- Constants are now resource keys of
NoiseSettingsno longer takes in the vertical and horizontal sizecreateno longer takes in the vertical and horizontal sizegetCellHeight,getCellWidthare removed
OreVeinifierreplaced byOreVeinRuleOverworldFunctionSet- A set of functions applied to construct the overworld.RandomStatecreatenow takes in the holder getter forNormalNoiseinstead of theHolderGetter$Provider, and the rawNoiseGeneratorSettingsinstead of aResourceKey- The overload also takes in default values for using legacy randomization, the default
BlockState,intsea level, andNoiseRouter
- The overload also takes in default values for using legacy randomization, the default
samplersWithContext- Creates a new sampler set with the given context.createClimateSampler- Creates a climate sampler from the given context.getOrCreateNoisenow takes in a resource key ofNormalNoiseinstead ofNormalNoise$NoiseParameters, returning theNoiseinsetad ofNormalNoiserouteris removedsamplerreplaced bygetSampler, not one-to-oneaquiferRandom,oreRandomare removedsampleBlockValueUncached- Samples the block value at the given position.acquireDensityBufferPool,releaseDensityBufferPool,garbageCollect- Handles the density buffer management.seed- The seed of the random state.
SpawnTargetPoint- A potential location to spawn the player, determined by its map of density function to climate parameters.- This is analogous to
Climate$ParameterPoint
- This is analogous to
SurfaceRules->MaterialRules, not one-to-one$ConditionSourceconstants have been moved toVanillaMaterialConditions, now referenced by theirResourceKeyregisterAndWrap- Registers a material rule and wraps it in a holder.getRule- Gets a material rule and wraps it in a holder.getCondition- Gets a material condition and wraps it in a holder.$AbovePreliminarySurface->AbovePreliminarySurfaceCondition$Bandlands->BandlandsRule$BiomeConditionSource->BiomeCondition$BlockRuleSource->BlockRule$Condition->ConditionEvaluator$ConditionSource->MaterialConditionbootstrap->bootstrapConditions
$Context->MaterialRuleContext, not one-to-one- Constructor is now package-private from
protected updateXZ,updateYare now package-private fromprotectedgetSurfaceSecondary,getBiome,getMinSurfaceLevelare nowpublicfromprotectedgetNoiseSampleris nowpublicfromprotectedgetOrCreateRandomFactory- Crates a random positional factory if not present for the identifier.getDensitiesInChunk- Provides a getter to sample the density values for the given context.possibleBiomes- The biomes that can be possibly selected.stoneDepthAbove,stoneDepthBelow,surfaceDepth- Depth values for material locations.waterHeight- The height of the water.blockX,blockY,blockZ,blockPos- The current block position.surfaceGradientX,surfaceGradientZ- The horizontal surface gradients.resolveAnchorY- Resolves the anchor to a Y value.getBand- Gets the band that should generate at the given position.$AbovePreliminarySurfaceCondition$HoleCondition-> Anonymous class inHoleCondition$SteepMaterialCondition-> Anonymous class inSteepCondition$TemperatureHelperCondition-> Lambda inTemperatureCondition
- Constructor is now package-private from
$Hole->HoleCondition$LazyConditionis removed$LazyXZCondition->MaterialRuleContext$LazyXZCondition$LazyYCondition->MaterialRuleContext$LazyYCondition$NoiseThresholdConditionSource->NoiseThresholdCondition$NotCondition-> Lambda inNotCondition$NotConditionSource->NotCondition$RuleSource->MaterialRulebootstrap->bootstrapRulesapply->compile
$SequenceRule-> Lambda inSequenceRule$SequenceRuleSource->SequenceRule$StateRule->BlockRule$Steep->SteepCondition$StoneDepthCheck->StoneDepthCondition$SurfaceRule->RuleEvaluator$Temperature->TemperatureCondition$TestRule-> Lambda inConditionRule$TestRuleSource->ConditionRule$VerticalGradientConditionSource->VerticalGradientCondition$WaterConditionSource->WaterCondition$YConditionSource->YCondition
SurfaceSystem->MaterialSystem, not one-to-one- The constructor no longer takes in the preliminary surface
DensityFunction buildSurfaceno longer takes in the legacy randombooleantopMaterialnow takes in theWorldGenerationContext, and aDensitySamplerSetinstead of aNoiseChunkpreliminarySurfaceFunction- The density function used to generate the prelimiary surface.
- The constructor no longer takes in the preliminary surface
VerticalAnchor#relativeToSeaLevel,seaLevel,$RelativeToSeaLevel- Gets a vertical anchor offset from the sea level.WorldGenerationContextof- Creates the context from theLevelAccessor.seaLevel- The sea level of the world.
net.minecraft.world.level.levelgen.blendingBlenderCONTEXT_KEY,ALPHA_KEY,OFFSET_KEY- Keys for the blender and density samplers.blendOffsetAndFactornow has an overload that takes in aDensityVolumeinstead of the block XZints.blendDensitynow takes in the block XYZints instead of theDensityFunction$FunctionContext, afloatinstead of adoublefor the noise value, and returns afloatinstead of adoublegetCarvingFilter- Returns the carving filter.addAroundOldChunksCarvingMaskFilter->createAroundOldChunksCarvingMaskFilter, nowprivatefrompublic$BlendingOutputis nowprotectedfrompublic$OutputBuffer- A wrapper that handles creating the samplers that outputs the blender data.
BlendingDataNO_VALUEis now afloatinstead of adoublegetHeight,getDensitynow returnsfloats instead ofdoubles$DensityConsumer#consumenow takes in afloatinstead of adoublefor the density$HeightConsumer#consumenow takes in afloatinstead of adoublefor the height$Packedenow takes in an array offloats instead ofdoubles for the heights
net.minecraft.world.level.levelgen.blockpredicatesBlockPredicatetestnow takes in aLevelAccessorinstead of aWorldGenLevelmatchesBlocks(List<Block>)is removedmatchesBlocks(Vec3i, Block...)->matchesBlocks(Directional, Block...)matchesTagnow hsa an overload that takes in aDirectionalmatchesFluids(Vec3i, Fluid...)->matchesBlocks(Directional, Fluid...)matchesBiomesis removedreplaceablecan no longer take in any parameterswouldSurvivenow just takes in only theBlockhasSturdyFace(Vec3i, Direction)->matchesBlocks(Directional, Direction)solidnow takes in aDirectionalinstead of aVec3inoFluidno longer takes in any parametersunobstructedno longer takes in any parametersheightRange- Specifies the height must be within the following range.volumeMatch- Specifies the block must match within the volume provided by two points.
HeightRangePredicate- A predicate that tests the block is between theVerticalAnchors defining the Y range.VolumeMatchPredicate- A predicate that tests all blocks within a volume matches the provided predicate.WouldSurvivePredicateconstructor is nowpublicfromprotected
net.minecraft.world.level.levelgen.carver*Configurationclasses are removed, merged onto the associated world carver- The world carvers are now commonly records that define the configuration data
CanyonWorldCarvernow only takes in thefloatprobaility, yHeightProvider, vertical rotationFloatProvider, and$Shape$CanyonShapeConfiguration->$Shape, now taking in the y scaleFloatProvider
CarverConfigurationis removedCarverDebugSettingsis removedCarvingContextis removed, usage replaced byWorldGenerationContextCaveWorldCarvernow takes in a countIntProvider, thicknessFloatProvider, abooleanfor whether to bias thickness for weirdness, andFloatProvidermultipliers for the vertical room and starting verial radiusConfiguredWorldCarveris removed, replaced byWorldCarverNetherWorldCarveris removedWorldCarveris now aninterfacefrom an abstractclassWorldCarverconstants are now inlined withinWorldCarverTypesBlockstateconstants are removedDIRECT_CODEC- The direct codec for dispatching the carver from its type.CODEC- The holder-wrapped entry.LIST_CODEC- The holder set entry.liquidsis removedconfiguredis removedconfiguredCodecreplaced bycodeccarveEllipsoidis nowstatic, returning nothing, no longer taking in theCarvingContext, configuration,ChunkAccess, biome getter, andAquifer, instead taking in theChunkPosandCarverOutputinstead of theCarvingMaskcarveBlockis removedcarvenow takes in aWorldGenerationContextinstead of theCarvingContext, aCarverOutputinstead of theCarvingMask, and theChunkPosinstead of theCarvingContext, configuration,ChunkAccess, biome getter, andAquiferisStartChunkno longer takes in the configurationcanReachis nowpublicfromprotected$CarveSkipChecker#shouldSkipno longer takes in theCarvingContext
net.minecraft.world.level.levelgen.densityfunctionCacheId- An identifier for a cached density function, goes unused.CachingDensitySampler- A density sampler that caches the sampled value for the specific volume.ContextBoundSampler- A density sampler that uses the sampler referenced by the givenContextKey, defaulting to the provided fallback if not available.DensityBuffer- A buffer for containing the sampled density values.DensityBufferArena- An interface for managing the allocation and release of density buffers.DensityBufferPool- A buffer arena holding some pool of density buffers, discarding any buffers older than a certain number of ticks.DensityFunctionCompiler- A compiler for optimizing and turningDensityFunctions intoDensitySamplers.DensitySampler- A compiled function to sample the density values at a given position.DensitySamplerSet- ADensitySamplergetter given its function.DensityVolume- A record defining some rectangular prism along with the step size when iterating through on each axis.DfRewriteRule- An interface for rewriting density functions, typically for execution optimization.DistanceMetric- The available metrics to define how distance should be measured.SamplerContext- The context provided when aDensitySampleris sampling a value.ScopedDensityBuffer- A density buffer that is scoped to some arena, keeping track of its current age in ticks.TilingMode- A mode used for when sampling outside of a mapped range (e.g. gradient functions).
net.minecraft.world.level.levelgen.densityfunction.generatorDistancetoPointFunction- Determines the distance to the provided point using the specified metric.SimpleDensityFunction- An enum for defining a sampler constructed when theNoiseChunkwas first initialized.
net.minecraft.world.level.levelgen.densityfunction.opLerpFunction- A function that linearly interpolates between two other functions, selecting a point based on an alpha function.PowFunction- A function that raises the base to the sampled exponent.RoundFunction- A function that rounds the sampled value to anintusing the provided$Type.SliceFunction- A function that samples the input along the given axis with the fixed coordinate.
net.minecraft.world.level.levelgen.feature- Features are now commonly either records that contain the configuration data, or interfaces / abstract classes that define a common subtype
- Feature clases typically provide a
MapCodecfield namedCODECthat is used for registration AbstractHugeMushroomFeatureis now aninterfacefrom an abstractclassplaceTrunkis nowpublicfromprotected, no longer taking in the configurationplaceMushroomBlockis nowpublicfromprotectedgetTreeHeightis nowpublicfromprotectedisValidPositionis nowpublicfromprotected, no longer taking in the configurationgetTreeRadiusForHeightis nowpublicfromprotectedmakeCapis nowpublicfromprotectedcapProvider- TheBlockStateProviderused to select the blocks for the mushroom cap.stemProvider- TheBlockStateProviderused to select the blocks for the mushroom stem.foliageRadius- The radius of the mushroom cap.canPlaceOn- Whether this feature can be placed on the below block.
AbstractOreFeature- An abstract implementation to place ore.BasaltColumnsFeaturereplaced bySteppedColumnClusterFeature, with cluster reach and column count more randomized withWeightedRandomSelectorFeatureBasaltPillarFeaturereplaced byOverlayFeaturemergingSingleBlockPillarFeature, sometimes withProjectedRandomPatchySquareandSimpleBlockFeature- Main replacement would be
SingleBlockPillarFeature, followed byOverlayFeature layernow has an overload that takes in a holder-wrappedBlockStateProviderinstead of the raw value
- Main replacement would be
ConfiguredFeaturerecord is removed, replaced byFeaturegetSubFeatures->Feature#getSubFeatures, now a stream of holder-wrappedFeatures
CoralClawFeaturenow takes in a holder-wrappedPlacedFeatureto use instead of generating the coral block itselfCoralFeatureclass is removedCoralMushroomFeatureclass is removed, replaced by anOverlayFeatureofSimpleBlockFeaturesCoralTreeFeaturenow takes in a holder-wrappedPlacedFeatureto use instead of generating the coral block itselfCuboidPlacement- Places the feature in the form of a cuboid, placing against the edges or interior depending on the setbooleans.DesertWellFeaturereplaced by anOverlayFeatureofTemplateFeaturesEndPodiumFeature#getLocationis removedEndSpikeFeature#NUMBER_OF_SPIKESis nowprivatefrompublicFallenTreeFeature#builder- Creates the builder for the fallen tree.Featureis now aninterfacefrom an abstractclassFeatureconstants are now inlined withinFeatureTypesDIRECT_CODEC- The direct codec for dispatching the feature from its type.CODEC- The holder-wrapped entry.LIST_CODEC- The holder set entry.configuredCodecreplaced bycodecisReplaceableis removedsafeSetBlockis nowpublicfromprotectedplacenow takes in theWorldGenLevel,ChunkGenerator,RandomSource, and originBlockPos- All other
placemethods are removed
- All other
checkNeighbors->AbstractOreFeature#checkNeighborsisAdjacentToAir->AbstractOreFeature#isAdjacentToAirmarkAboveForPostProcessingis nowpublicfromprotected
FeatureCountTracker#featurePlacednow takes in aFeatureinstead of aConfiguredFeatureFeaturePlaceContextclass is removedFeatureTypes- All vanilla feature types.FossilFeatureConfigurationclass is removedGlowstoneFeaturereplaced byRandomNeighborSpreadFeatureHugeFungusConfigurationclass is removedKelpFeaturereplaced byBlockColumnFeatureLakeFeature$Configurationmerged ontoLakeFeatureMultifaceGrowthFeature#placeGrowthIfPossibleis no longerstatic, and no longer takes in the configurationNetherForestVegetationFeaturereplaced bySimpleBlockFeaturewith some additionalPlacementModifiers for determining spreadOreFeaturenow extendsAbstractOreFeaturedoPlaceno longer takes in the configurationcanPlaceOre->AbstractOreFeature#canPlaceOre, no longerstatic, no longer taking in the configurationshouldSkipAirCheck->AbstractOreFeature#shouldSkipAirCheck, nowprivatefromprotected
OverlayFeature- A feature that placesPlacedFeatures, returning success if any feature was placed.- OR variant of
SequenceFeature
- OR variant of
ProjectedRandomPatchySquare- A feature that spawns a square, where each block has a probability to spawn, by projecting downwards until hitting a block it cannot go through or the max height.RandomNeighborSpreadFeature- A feature that places the provided block at the sampled position for n attempts as long as there is one accepted neighbor.ScatteredOreFeaturenow extendsAbstractOreFeatureSculkPatchFeatureno longer takes in theIntProviderfor extra rare growths and the associatedfloatcatalyst chanceSeagrassFeaturereplaced by aWeightedRandomSelectorFeatureofSimpleBlockFeaturesSeaPickleFeaturereplaced bySimpleBlockFeatureSingleBlockPillarFeature- A feature that places a pillar in the associated direction, optionally providing a cap.SteppedColumnClusterFeature- A feature that places a cluster of columns upwards.TemplateFeaturenow takes in an optional holder-wrappedStructureProcessorListto applyTreeFeatureBlockStateProviders are now holder-wrappedTwistingVinesFeaturereplaced byBlockColumnFeatureVegetationPatchFeatureis still aclass- All instance fields are
protectedfrompublic groundStateis now holder-wrappedplaceGroundPatchno longer takes in the configurationdistributeVegetationis nowprivatefromprotectedplaceVegetationno longer takes in the configurationplaceGroundis nowprivatefromprotected
- All instance fields are
WeepingVinesFeaturereplaced by anOverlayFeatureofRandomNeighborSpreadFeatureandBlockColumnFeature
net.minecraft.world.level.levelgen.feature.configurationsis removed- All
*Configurationclasses are removed, merged onto their associated feature OreConfigurationtarget->BlockReplacement#replace$TargetBlockState->BlockReplacement
FallenTreeConfiguration$FallenTreeConfigurationBuilder->FallenTreeFeature$BuilderTreeConfiguration$TreeConfigurationBuilder->TreeFeature$BuilderVegetationPatchConfiguration#CODEC->VegetationPatchFeature#makeCodec, not one-to-one
- All
net.minecraft.world.level.levelgen.feature.foliageplacersFoliagePlacercreateFoliagenow takes in theTreeFeatureinstead of the configurationfoliageHeightnow takes in theTreeFeatureinstead of the configurationplaceLeavesRownow takes in theTreeFeatureinstead of the configurationplaceLeavesRowWithHangingLeavesBelownow takes in theTreeFeatureinstead of the configurationtryPlaceExtensionnow takes in theTreeFeatureinstead of the configurationtryPlaceLeafnow takes in theTreeFeatureinstead of the configuration$FoliageAttachmentis now a record- The constructor no longer takes in a
booleanfor the double trunk, instead taking in anintfoliage height offset, and the XZ sizeints radiusOffset->radiusOffsetXZ
- The constructor no longer takes in a
PoplarFoliagePlacer- The foliage placer for poplar trees.
net.minecraft.world.level.levelgen.feature.rootplacersAboveRootPlacementnow takes in a holder-wrappedBlockStateProviderinstead of the raw valueMangroveRootPlacementnow takes in a holder-wrappedBlockStateProviderinstead of the raw valueMangroveRootPlacernow takes in a holder-wrappedBlockStateProviderinstead of the raw valueRootPlacernow takes in a holder-wrappedBlockStateProviderinstead of the raw valuerootProvideris now a holder-wrappedBlockStateProviderinstead of the raw valueplaceRootsnow takes in theTreeFeatureinstead of the configurationplaceRootnow takes in theTreeFeatureinstead of the configuration
net.minecraft.world.level.levelgen.feature.stateprovidersBlockStateProvideris now aninterfacefrom an abstractclassCODEC->TYPED_CODECCODECis now the holder-wrapped provider
STATE_OR_PROVIDER_CODEC- Takes in either aBlockStateorBlockStateProvider.DIRECT_CODEC- The datapack registry codec.simple->ofholderOf- Returns the holder-wrapped provider from the block.typereplaced bycodec, now returning aMapCodecgetState,getOptionalStatenow take in aLevelAccessorinstead of theWorldGenLevel
BlockStateProviderTypeclass is removed- Constants are now inlined in
BlockStateProviderTypes codec->BlockStateProvider#codec
- Constants are now inlined in
BlockStateProviderTypes- Registers all vanilla block state providers.CopyPropertiesProvider- A provider that copies the properties of the block at the placed position.DualNoiseProvidernow take inNormalNoises instead ofNormalNoise$NoiseParametersfor the parametersgetSlowNoiseValuenow returns afloatfrom adouble
NoiseBasedStateProvidernow takes inNormalNoiseinstead ofNormalNoise$NoiseParametersfor the parametersnoiseCodecnow returns aP3containingNormalNoiseinstead ofNormalNoise$NoiseParametersparametersis nowNormalNoiseinstead ofNormalNoise$NoiseParametersnoiseis nowNoiseinstead ofNormalNoisegetNoiseValuenow returns afloatfrom adouble
NoiseProvidernow takes inNormalNoiseinstead ofNormalNoise$NoiseParametersfor the parametersnoiseProviderCodecnow returns aP4containingNormalNoiseinstead ofNormalNoise$NoiseParametersgetRandomStatenow takes in afloatfrom adouble
NoiseThresholdProvidernow takes inNormalNoiseinstead ofNormalNoise$NoiseParametersfor the parametersRandomBlockProvider- A provider that selects a random block from the given set.RandomizedIntStateProvidernow takes in a holder-wrappedBlockStateProviderinstead of the raw valueRotatedBlockProvideris now a record- The constructor now takes in a holder-wrapped
BlockStateProviderinstead of aBlock, and an optionalDirectionto face
- The constructor now takes in a holder-wrapped
RuleBasedStateProvideris now a record- The constructor now takes in a holder-wrapped
BlockStateProviderinstead of the raw value $Rulenow takes in a holder-wrappedBlockStateProviderinstead of the raw value
- The constructor now takes in a holder-wrapped
SimpleStateProvideris now a recordWeightedStateProvideris now a record
net.minecraft.world.level.levelgen.feature.treedecoratorsAlterGroundDecoratornow takes in a holder-wrappedBlockStateProviderinstead of the raw valueAttachedToLeavesDecoratornow takes in a holder-wrappedBlockStateProviderinstead of the raw valueAttachedToLogsDecoratornow takes in a holder-wrappedBlockStateProviderinstead of the raw valuePlaceOnGroundDecoratornow takes in a holder-wrappedBlockStateProviderinstead of the raw valueShelfMushroomDecorator- A "tree" decorator for the shelf mushroom.TreeDecorator$ContextisReplaceable- Checks whether the block at the given position can be replaced.isWaterOrWaterNearby- Checks if the given position or any adjacent positions are water blocks.
net.minecraft.world.level.levelgen.feature.trunkplacersPoplarTrunkPlacer- A trunk placer for the poplar tree.TrunkPlacerplaceTrunknow takes in theTreeFeatureinstead of the configurationplaceBelowTrunkBlocknow takes in theTreeFeatureinstead of the configurationplaceLognow takes in theTreeFeatureinstead of the configurationplaceLogIfFreenow takes in theTreeFeatureinstead of the configuration
net.minecraft.world.level.levelgen.material.MaterialRuleListrecord is removednet.minecraft.world.level.levelgen.placement- All placement modifier implementations are now generally records
FeaturePlacer- A helper for spawning a givenPlacedFeatureinto the worldPlacedFeaturenow takes in a holder-wrappedFeatureinstead of aConfiguredFeatureplaceWithBiomeCheck->FeaturePlacer#placeWithBiomeCheckgetFeaturesnow returns a stream of holder-wrappedFeatures instead of aConfiguredFeatures
PlacementContext#getCarvingMaskis removedPlacementFilteris now aninterfacefrom an abstractclassPlacementModifieris now aninterfacefrom an abstractclassgetPositions->modify, now taking in aConsumer<BlockPos>for the placements to copy rather than returning the stream ofBlockPosestypereplaced bycodec
PlacementModifierTypeis removed- All constants are now inlined in
PlacementModifierTypes#bootstrap codec->PlacementModifier#codec
- All constants are now inlined in
PlacementModifierTypes- Registers all vanilla placement modifier types.RandomChancePlacement- A placement that provides a probability of placing the feature.- Similar to
RarityFilter, though chance there is checked against the reciprocal.
- Similar to
RandomlySelectedPlacement- A placement modifier that randomly selects a modifier to apply from some list.RandomOffsetPlacement->OffsetPlacement, now separating the XZ spread into their ownIntProvidersofnow has overloads that can take in the XYZ constantintspread, or aDirectionabove- Creates an offset of one block above the given position.
RepeatingPlacementis now aninterfacefrom an abstractclass
net.minecraft.world.level.levelgen.structureBoundingBox#intersectsnow has an overload that can specify theintmin and max XYZ boundsStructuregeneratenow takes in theClimate$SampleronTopOfChunkCenter->onTopOfChunkCenterWithoutBiomeCheck- Original
onTopOfChunkCenternow checks whether a biome could exist on top of the chunk center and, iffalse, returns an empty optional
- Original
getLowestYIn5by5BoxOffset7Blocks->getLowestYIn5by5Box, now taking in the bloxk XZints$GenerationContextnow takes in theClimate$SamplerandBiomeResolverisValidBiome- Checks whether the given stub is in a valid biome.couldStructureExistInColumn- Checks whether a structure could exist in the block column due to a valid biome.couldValidBiomeExistInTerrainColumn- Checks whether a valid biome could exist in the column defined by the horizontal position.couldValidBiomeExistOnTopOfChunkCenter- Checks whether a valid biome could exist in the column at the chunk center.
StructurePiece#addChildrennow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorStructurePieceAccessorinterface is removed
net.minecraft.world.level.levelgen.structure.piecesPieceGeneratorinterface is removedPieceGeneratorSupplierinterface is removedStructurePiecesBuilderno longer implementsStructurePieceAccessor
net.minecraft.world.level.levelgen.structure.placementConcentricRingsStructurePlacementnow extendsAbstractSpreadingStructurePlacementDimensionOriginStructurePlacement- A placement that only allows the structure to spawn at the dimension's origin.RandomSpreadStructurePlacementnow extendsAbstractSpreadingStructurePlacementStructurePlacementis now aninterfacefrom an abstractclass- Original class implementation moved to
AbstractSpreadingStructurePlacement isStructureChunk,applyAdditionalChunkRestrictions,getLocatePos,locateOffsetremain as defined methodstypereplaced bycodec
- Original class implementation moved to
StructurePlacement- Registers all vanilla structure placement types.StructurePlacementTypeinterface is removed- All constants have been inlined in
StructurePlacements#bootstrap codec->StructurePlacement#codec
- All constants have been inlined in
net.minecraft.world.level.levelgen.structure.structuresIglooPieces#addPiecesnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorMineshaftPieces$MineShaftCorridor#findCorridorSizenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$MineShaftCrossing#findCrossingnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$MineShaftStairs#findStairsnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor
NetherFortressPieces$BridgeCrossing#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$BridgeEndFiller#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$BridgeStraight#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleCorridorStairsPiece#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleCorridorTBalconyPiece#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleEntrance#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleSmallCorridorCrossingPiece#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleSmallCorridorLeftTurnPiece#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleSmallCorridorPiece#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleSmallCorridorRightTurnPiece#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$CastleStalkRoom#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$MonsterThrone#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$NetherBridgePiecegenerateChildForwardnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorgenerateChildLeftnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorgenerateChildRightnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor
$RoomCrossing#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$StairsRoom#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor
NetherFossilPieces#addPiecesnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorOceanRuinPieces#addPiecesnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorShipwreckPieces#addRandomPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorStrongholdPieces$ChestCorridor#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$FillerCorridor#findPieceBoxnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$FiveCrossing#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$LeftTurn#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$Library#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$PortalRoom#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$PrisonHall#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$RightTurn#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$RoomCrossing#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$StairsDown#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$Straight#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$StraightStairsDown#createPiecenow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor$StrongholdPiecegenerateSmallDoorChildForwardnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorgenerateSmallDoorChildLeftnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessorgenerateSmallDoorChildRightnow takes in theStructurePiecesBuilderinstead of theStructurePieceAccessor
net.minecraft.world.level.levelgen.structure.templatesystemAllOfRuleTest- A test that checks if all rules returntrue, equivalent to AND.AnyOfRuleTest- A test that checks if any rule returntrue, equivalent to OR.HeightMatchTest- A test that checks whether the position is within the height bounds.NotRuleTest- A test that inverts the result of the given test, equivalent to NOT.RuleTesttestnow takes in aBlockPosallOf- Checks if all rules returntrue, equivalent to AND.anyOf- Checks if any rule returntrue, equivalent to OR.not- Inverts the result of the given test, equivalent to NOT.either- Uses the provided test depending on the result of the condition test, equivalent to IF/ELSE.
StructureTemplate$JigsawBlockInfonow takes in aBlockPosandBlockStateinstead of the$StructureBlockInfoof->parsewithInfonow takes in aBlockPosandBlockStateinstead of the$StructureBlockInfo
net.minecraft.world.level.levelgen.synthBlendedNoiseis now a record that implementsDensityFunctioninstead ofDensityFunction$SimpleFunctionDATA_CODEC->CODEC, nowpublicfromprivate- The original
CODEChas been removed
- The original
- The constructor no longer takes in the
RandomSource withNewRandomreplaced bycreateFbmSet, returning a$FbmSetcreateFbm- Creates noise into layers for fractional brownian motion.compileSamplernow has an overload that takes in theRandomSourceparityConfigString->$FbmSet#parityConfigString$FbmSet- A record containing the blended noise using fractional brownian motion.
GradientNoise- An abstract noise implementation that generates a gradient of values.ImprovedNoisereplaced byPerlinNoise,SmearedPerlinNoise; not one-to-onenoiseWithDerivate->PerlinNoise#noiseWithDerivativesampleAndLerp->PerlinNoise#sampleAndLerp, nowprivatefrompublic
Noise- An interface designed to sample a noise function for some position.NoiseStack- Layers different noises on top of each other, usualy with differing frequency and amplitudes.NormalNoiseis nowfinalcreatereplaced byNormalNoise$builder- An overload exists that takes in a
RandomSourceand returns aNoise
- An overload exists that takes in a
maxValuemerged intorangegetValueare removedparametersis removedparityConfigStringnow takes in theRandomSource$Builder- A builder to construct the normal noise to apply.$Normalization- How to apply normalization to the noise.$NoiseParametersreplaced by$Parameters, nowprivatefrompublicDIRECT_CODECreplaced byNormalNoise#DIRECT_CODECCODECreplaced byNormalNoise#CODEC- The original
CODECis now used to store the new$Parametersvalues
- The original
PerlinNoisenow extendsGradientNoisecreateLegacyForLegacyNetherBiome, or the original implementation ofPerlinNoise, replaced byLegacyFbmInitializer#createForLegacyNetherBiome,NormalNoise#createForLegacyNetherBiomecreatemethods are removed- The constructor no longer takes in the
Pair<Integer, DoubleList>andbooleanfor whether to initialize with a new position maxValuemerged intorangegetValuereplaced byget, now returning afloatmaxBrokenValueis removedgetOctaveNoise,wrap,firstOctave,amplitudesare removed
PerlinSimplexNoisereplaced bySimplexNoiseSimplexNoisesplit into its super implementationGradientNoise, andSimplexNoiseGRADIENT->GradientNoise#GRADIENT, now an array ofGradientNoise$GradientRANGE- The range of values that can be generated.STANDARD_DEVIATION- The standard deviation of the noise value.- The constructor no longer takes in a
booleanto discard the noise offset dot->GradientNoise$Gradient#dot, no longer taking in theint[]getValuereplaced byget, now returning afloat
SmearedPerlinNoise- A perlin noise implementation that fudges the scaling in the Y direction.
net.minecraft.world.level.storage.lootContainerComponentManipulatoris now arecordinstead of aninterfacesetContents(T, Stream<ItemStack>)is removedgetContentsis removed
FloatRangePredicate- A predicate that checks whether the float is on the line, or matches the point.IntRangesplit intoIntLimitfor the limiter, andIntRangePredicatefor the checker- Both now extend / implement
Validatableinstead ofLootContextUser
- Both now extend / implement
LootContextgetParameteris removedgetOptionalParameter->getOptionalcreateVisitedEntrynow has an overload that takes in and returns aSlotSource
LootContextArgof- Constructs an argument of aContextKey.$ArgCodecBuilder#or- Adds an argument to choose from.
LootDataTypeno longer takes in aCodecSLOT_SOURCE- Slot source to choose from.FLOAT_PROVIDER- Float providers to sample a value.INT_PROVIDER- Integer providers to sample a value.runValidationnow has an overload that takes in aHolderLookup$Providerinstead of aHolderLookuprunValidationIfPresent- Runs the validation if the registry is present.
LootPool$BuildersetRollsnow takes in a holder-wrappedContextIntProviderinstead of aNumberProvidersetBonusRollsnow takes in a holder-wrappedContextFloatProviderinstead of aNumberProvider
LootTable#LIST_CODEC- The holder set codec.Validatable#validateReferencereplaced byvalidateHolder,validateHolderSet, now taking in theStringname and eitherHolders orHolderSetsValidationContextenterTag- Enters into a tag object.hasVisitedTag- If the tag has already been visited.allowsReferencesis removed$MissingReferenceProblemis removed$MinBoundsProblem- A problem where the backing list must contain at least the given number of elements.$RecursiveReferenceProblemsplit into$RecursiveElementReferenceProblem,$RecursiveTagReferenceProblem$ReferenceNotAllowedProblemis removed
net.minecraft.world.level.storage.loot.entries- Subtypes of
LootPoolEntryContainernow take in an optional holder-wrappedLootItemConditionand an optional holder-wrappedLootItemFunctioninstead of other condition and function variations AlternativesEntry$Buildernow implementsCompositeEntryBase$Builderinstead ofLootPoolEntryContainer$BuilderCompositeEntryBase$Builder- An abstract builder for creating a composite subtype.$CompositeEntryConstructor#createnow takes in an optional holder-wrappedLootItemConditioninstead of a list ofLootItemConditions, and an optional holder-wrappedLootItemFunction
DynamicLootnow extendsSingleEntryContainerBasedynamicEntrynow returns aUniformContainerBase$Builder
EmptyLootItemnow extendsSingleEntryContainerBaseemptyItemnow returns aUniformContainerBase$Builder
EntryGroup$Buildernow implementsCompositeEntryBase$Builderinstead ofLootPoolEntryContainer$BuilderExpandableContainerBase- A uniform container that can expand its data into separate consumed values or given in a single entry, typically for use with pools that reference a range of objects.LootItemnow extendsSingleEntryContainerBaselootTableItemnow returns aUniformContainerBase$Builder
LootPoolEntryContainernow takes in an optional holder-wrappedLootItemConditionand an optional holder-wrappedLootItemFunctioninstead of other condition and function variationsmodifier- The function to apply to the items.commonFieldsnow returns aP2containing an optional holder-wrappedLootItemConditionand an optional holder-wrappedLootItemFunctioncanRunis nowprivatefromprotectedexpandis nowfinal- Use
expandRawinstead, which is called after making sure the container can run
- Use
$Buildernow implementsFunctionUserBuildergetConditions->getCondition, now returning an optional holder-wrappedLootItemCondition.getModifier- Gets the function modifier.
LootPoolSingletonContainersplit intoUniformContainerBaseandSingleEntryContainerBasedepending on usageNestedLootTablenow extendsExpandableContainerBaseINLINE_LOOT_TABLE_PATH_ELEMENTis removedlootTableReferencenow returns aUniformContainerBase$Builder
SequentialEntry$Buildernow implementsCompositeEntryBase$Builderinstead ofLootPoolEntryContainer$BuilderSingleEntryContainerBase- A uniform container that outputs a single entry.SlotLootnow extendsSingleEntryContainerBaseTagEntrynow extendsExpandableContainerBasetagContents,expandTagnow take in an itemHolderSetinstead of aTagKey, returning aUniformContainerBase$Builder
UniformContainerBase- A container whose entries can be weighted, affected by the quality scalar of luck.
- Subtypes of
net.minecraft.world.level.storage.loot.functions- Subtypes of
LootItemConditionalFunctionnow take in an optional holder-wrappedLootItemConditioninstead of some other condition variation EnchantedCountIncreaseFunctionlootingMultipliernow takes in an enchantmentHolderGetterinstead of theHolderLookup$Provider, and a holder-wrappedContextIntProviderinstead of aNumberProvider$Buildernow takes in a holder-wrappedContextIntProviderinstead of aNumberProvider
EnchantRandomlyFunction#randomApplicableEnchantmentnow takes in an enchantmentHolderGetterinstead of theHolderLookup$ProviderEnchantWithLevelsFunctionenchantWithLevelsnow takes in an enchantmentHolderGetterinstead of theHolderLookup$Provider, and a holder-wrappedContextIntProviderinstead of aNumberProvider$Buildernow takes in a holder-wrappedContextIntProviderinstead of aNumberProvider
ExplorationMapFunctionDEFAULT_DESTINATIONis removedmakeExplorationMap,$Buildernow takes in a structureHolderSet$Builder#setDestinationis merged into the constructor
FilteredFunction$Builder#onPass,onFailnow take in the rawLootItemFunctioninstead an optional-wrapped oneFunctionReferenceclass is removedFunctionUserBuilderapplynow has an overload that takes in a holder-wrappedLootItemFunctioninstead of theLootItemFunction$BuilderbuildFunction- Builds a function from a list of functions.
LimitCount#limitCountnow takes in anIntLimitinstead of anIntRangeLootItemConditionalFunctionnow takes in an optional holder-wrappedLootItemConditioninstead of a list ofLootItemConditionscommonFieldsnow returns aP1containing an optional holder-wrappedLootItemConditioninstead of a list ofLootItemConditionssimpleBuildernow takes in a function with an input of an optional holder-wrappedLootItemConditioninstead of a list ofLootItemConditions$BuildergetConditions->getCondition, now an optional holder-wrappedLootItemConditioninstead of a list ofLootItemConditions$DummyBuildernow takes in a function with an input of an optional holder-wrappedLootItemConditioninstead of a list ofLootItemConditions
LootItemFunction#decoratenow takes in an optional holder-wrappedLootItemFunctioninstead of aBiFunctionLootItemFunctionsIDENTITY->SequenceFunction#IDENTITY, nowprivatefrompublicROOT_CODEC->DIRECT_CODECLIST_CODEC- The holder set codec.composereplaced byFunctionUserBuilder#buildFunction
SequenceFunctionnow extendsLootItemConditionalFunction- The constructor is now
publicfromprivate canUseInlineCodec- Whether the inline codec can be used for this sequenceofnow takes in a list of holder-wrappedLootItemFunctions instead of the raw valueapply->run
- The constructor is now
SetAttributesFunction#modifier,$ModifierBuildernow take in a holder-wrappedContextFloatProviderinstead of aNumberProviderSetContainerLootTableID_ONLY_CODEC- A codec that only takes in a loot table by its id.withLootTablenow takes in a loot tableHolder$Referenceinstead of theBlockEntityTypewith the loot tableResourceKey
SetCustomModelDataFunctionnow takes holder-wrappedContextFloatProviders for the floats, and holder-wrappedContextIntProviders for the colorsSetEnchantmentsFunction$Builder#withEnchantmentnow takes in a holder-wrappedContextIntProviderinstead of aNumberProviderSetItemCountFunction#setCountnow takes in a holder-wrappedContextIntProviderinstead of aNumberProviderSetItemDamageFunction#setDamagenow takes in a holder-wrappedContextFloatProviderinstead of aNumberProviderSetOminousBottleAmplifierFunction#setAmplifiernow takes in a holder-wrappedContextIntProviderinstead of aNumberProviderSetRandomDyesFunction#withCountnow takes in a holder-wrappedContextIntProviderinstead of aNumberProviderSetStewEffectFunction$Builder#withEffectnow takes in a holder-wrappedContextIntProviderinstead of aNumberProvider- An overload also allows for an
int
- An overload also allows for an
- Subtypes of
net.minecraft.world.level.storage.loot.parametersLootContextParams#CONTAINER- A parameter for the active container referenced as aSlotProvider.LootContextParamSetsCOMMAND_SLOT_SOURCE- For getting the slots from some container provided in a command.COMMAND_COMPUTE_DEFAULT- For running the default compute command.COMMAND_COMPUTE_POSITION- For running the block compute command.COMMAND_COMPUTE_ENTITY- For running the entity compute command.CONTAINER_PROCESS- For getting a container that is processing something (e.g. furnace cooking, brewing stand brewing).bootstrap- Returns all parameters in the context key set.validate- Validates that all context kets are inALL_PARAMS.
net.minecraft.world.level.storage.loot.predicatesAllOfConditionINLINE_CODECis removedallOfnow takes in a holder set ofLootItemConditions instead of a list
AnyOfCondition$Builder#ornow has an overload that takes in a holder-wrappedLootItemConditionCompositeLootItemConditionnow takes in a holder set ofLootItemConditions instead of a listholdersToLazyPredicates- Converts a holder set ofLootItemConditionto a list of lazy predicates.createCodecnow takes in a function with an input of a holder set ofLootItemConditions instead of a listcreateInlineCodecis removed$BuilderaddTermnow has an overload that takes in a holder-wrappedLootItemConditioncreatenow takes in a holder set ofLootItemConditions instead of a list
ConditionReferencerecord is removedConditionUserBuilderwhennow has an overload that takes in a holder-wrappedLootItemConditioninstead of theLootItemCondition$BuilderbuildCondition- Builds a condition from a list of conditions.
EntityHasScoreConditionnow takes in a score map with a value ofIntRangePredicates instead ofIntRanges$Builder#withScorenow takes in anIntRangePredicateinstead of anIntRange
InvertedLootItemConditionnow takes in a holder-wrappedLootItemConditioninstead of the raw valueinvertnow has an overload that takes in a holder-wrappedLootItemCondition
LocationChecknow takes in aVec3iinstead of aBlockPoscheckLocationnow takes in aVec3iinstead of aBlockPos- It also has an overload that takes in a
Direction
- It also has an overload that takes in a
LootItemBlockStatePropertyConditionreplaced byMatchBlock, not one-to-oneLootItemConditionTYPED_CODEC->DIRECT_CODEC- Original
DIRECT_CODECis removed
- Original
LIST_CODEC- The holder set codec.
LootItemConditions->LootItemConditionTypesLootItemRandomChanceConditionnow takes in a holder-wrappedContextFloatProviderinstead of aNumberProviderrandomChancenow takes in a holder-wrappedContextFloatProviderinstead of aNumberProvider
LootItemRandomChanceWithEnchantedBonusCondition#randomChanceAndLootingBoostnow takes in an enchantmentHolderGetterinstead of theHolderLookup$ProviderLootPredicates- All vanilla reference registeredLootItemConditions. Most conditions are inlined into the loot table.TimeChecknow takes in anIntRangePredicateinstead of anIntRangeValueCheckConditionsplit intoFloatValueCheckforfloats, andIntValueCheckforints
net.minecraft.world.level.storage.loot.providers.numberAggregateProvider- A provider that aggegates a set of other providers together.BinaryProvider- A provider that performs an operation on two other providers.BinomialDistributionGenerator->.ints.BinomialDistributionGenerator, nofloatvariantConditionalProvider- A provider that determines which provider to use based on the result of aLootItemCondition.ConstantValue->.floats.ConstantValue,.ints.ConstantValueDispatcherProvider- A provider that determines which provider to use based on the first attachedLootItemConditionthat returns true, otherwise defaulting to a specified provider. Basically a find first implementation.DistributionProvider- A provider that selects which provider to use from a weighted list.EnchantmentLevelProvider->.floats.EnchantmentLevelProvider, nointvariant; now implementsLootContextUserEnvironmentAttributeProvider- A provider that reads the value of anEnvironmentAttribute.EnvironmentAttributeValue->.floats.EnvironmentAttributeValue,.ints.EnvironmentAttributeValue; now implementsEnvironmentAttributeProviderNumberProvidersplit intoContextIntProvider,ContextFloatProvider- Now extends
Validatableinstead ofLootContextUser getFloat->ContextFloatProvider#getFloatgetInt->ContextIntProvider#getInt
- Now extends
NumberProviderssplit intoContextIntProviderTypes,ContextFloatProviderTypesTYPED_CODECmerged intoContextIntProviders#DIRECT_CODEC,ContextFloatProviders#DIRECT_CODECCODEC->ContextIntProviders#DIRECT_CODEC,ContextFloatProviders#DIRECT_CODECCODECis now the holder-wrapped variant
PowerProvider- A provider that raises some base provider to an exponent provider.RangeProvider- A provider that can provide a value between the provider ranges.ScoreboardValue->.ints.ScoreboardValue, nofloatvariantStorageValue->.floats.StorageValue,.ints.StorageValue; now taking in aStoredNumberAccessinstead of theIdentifierandNbtPathArgument$NbtPath, and a fallback providerStoredNumberAccess- An accessor that reads the number from the storage with the specified id, navigated to by the given path.Sum->.floats.Sum,.ints.Sum; now implementsAggregateProviderUnaryProvider- A provider that operates upon itself.UniformGenerator->.floats.UniformGenerator,.ints.UniformGenerator; now implementsRangeProvider
net.minecraft.world.level.storage.loot.providers.number.{floats, ints}(Indicates there is both a float and int provider variant)Absolute- Takes the absolute value of the sampled provider.Average- Takes the average of all sampled providers.ConditionalValue- Uses the true provider if theLootItemConditionreturnstrue, otherwise uses the false provider.Difference- Takes the difference of the sampled left and right providers.Maximum- Takes the maximum sampled value across the providers.Minimum- Takes the minimum sampled value across the providers.Modulus- Takes the modulo of the sampled left provider via the sampled right provider.Negate- Flips the sign of the sampled provider.NumberDispatcher- Uses the provider whoseLootItemConditionfirst returnstrue, otherwise uses the fallback provider. Basically a find first implementation.Power- Takes the sampled base provider to the sampled exponent provider.Product- Multiplies all sampled providers together.Quotient- Divides the sampled left provider by the sampled right provider.WeightedListValue- Picks a random weighted provider.
net.minecraft.world.level.storage.loot.providers.number.floatsCeiling- Ceils the sampledfloat.ContextFloatProvider- Provides afloatvalue given theLootContext.ContextFloatProviders- All vanilla reference registeredfloatproviders. Most providers are inlined in the loot table.ContextFloatProviderTypes- All registeredfloatprovider types.Cosine- Takes the cosine of the sampledfloat.Floor- Floors the sampledfloat.FromInt- Converts a sampledintto afloat.Length- Calculates the euclidean distance of all sampledfloats.ResolvableFloat- A lazy supplied reference to a constant orResourceKey<ContextFloatProvider>. This is for use outside the datapack context, like data components.Round- Rounds the sampledfloatto the nearestint.Sine- Takes the sine of the sampledfloat.SquareRoot- Takes the square root of the sampledfloat.Truncate- Truncates thefloatto theintclosest to 0.
net.minecraft.world.level.storage.loot.providers.number.intsContextIntProvider- Provides anintvalue given theLootContext.ContextIntProviders- All vanilla reference registeredfloatproviders. Most providers are inlined in the loot table.ContextIntProviderTypes- All registeredintprovider types.FloorModulus- Takes the modulo of the sampled leftintvia the sampled rightint, flooring towards the largest value less than the rightintif the signs differ.FloorQuotient- Divides the sampled leftintby the sampled rightint, flooring towards the largest value less than the rightintif the signs differ.FromFloat- Converts a sampledfloatto anint.ResolvableInt- A lazy supplied reference to a constant orResourceKey<ContextIntProvider>. This is for use outside the datapack context, like data components.
Minor Migrations
The following is a list of useful or interesting additions, changes, and removals that do not deserve their own section in the primer.
Command Responses
CommandResponseTracker is a method of handling the response to send during a command, tracking how many times a given element was successfully handled. The tracker can be broken into three parts: creating the tracker, tracking what values are returned by the command, and sending the feedback message based on the result.
The tracker is created by calling CommandResponseTracker#create, specifying the generic of the object being tracked:
// In some command method
private static int exampleCommandMethod(CommandSourceStack source, Collection<? extends Entity> entities) throws CommandSyntaxException {
// We are tracking entities in our command
CommandResponseTracker<Entity> tracker = CommandResponseTracker.create();
// ...
}
Then, CommandResponseTracker#track is used to keep track of the specific count we care about. The amount counted is either 1 if only the element is passed in, a 1 or 0 if a boolean is provided, or the raw count int:
// In some command method.
private static int exampleCommandMethod(CommandSourceStack source, Collection<? extends Entity> entities) throws CommandSyntaxException {
// ...
for (Entity entity : entities) {
// Tracking whether the entity has a glowing tag.
// 1 if yes, 0 is no.
tracker.track(entity, entity.hasGlowingTag);
}
}
Finally, to determine what message to display to get, we call CommandResponseTracker#sendFeedback, providing the CommandSourceStack, a boolean for whether the message should broadcast to the admins, and the messages to display depending on the scenario.
The messages are constructed using a CommandResponseTracker$Messages, $MessagesWithArg, or MessagesWithArgs, each taking zero, one, or two additional arguments, respectively, to pass to the message. They are constructed via CommandResponseTracker#messages, taking in an optional error handler to throw, a message if one object was successfully handled, and a general message if multiple objects were successfully handled:
// In the same location as the command method.
// The first argument should match the generic of the tracker.
// The other arguments are arbitrary depending on use case.
private static final CommandResponseTracker.MessagesWithArg<Entity, Integer> RESPONSE_EXAMPLE = CommandResponseTracker.messages(
// The error to throw on failure.
// This is optional, if none is specified, then no error will ever be thrown.
// Can either be a `SimpleCommandExceptionType`, or some function that takes in the argument and returns a `CommandSyntaxException`.
new SimpleCommandExceptionType(Component.translatable("commands.examplemod.example.failed")),
// The message to display on single success.
// This takes in the object generic, the total value tracked (what's returned to the command), and any additional arguments used.
// It returns the message to display.
(entity, totalValue, arg) -> Component.translatable("commands.examplemod.example.success.single", entity.getDisplayName(), totalValue, arg),
// The message to display on multiple success.
// This takes in the total number of objects tracked, the total value tracked (what's returned to the command), and any additional arguments used.
// It returns the message to display.
(entityCount, totalValue, arg) -> Component.translatable("commands.examplemod.example.success.multiple", entityCount, totalValue, arg)
);
// In some command method.
private static int exampleCommandMethod(CommandSourceStack source, Collection<? extends Entity> entities) throws CommandSyntaxException {
// ...
// Returned the tracked total value
return tracker.sendFeedback(
// The command source stack.
source,
// Whether to broadcast the message to the admins.
true,
// What entity to provide during a single success.
// This is either:
// - `ANY`, which chooses the first tracked entity.
// - `NON_ZERO`, which chooses the first tracked entity that provides a non-zero value.
// If not specified, it defaults to `NON_ZERO`
CommandResponseTracker.ElementType.NON_ZERO,
// The response messages to choose from.
RESPONSE_EXAMPLE,
// Any additional arguments passed to the message handler.
42
);
}
If sendFeedback is too limiting, you can determine what to do by calling dispatch instead:
// In some command method.
private static int exampleCommandMethod(CommandSourceStack source, Collection<? extends Entity> entities) throws CommandSyntaxException {
// ...
boolean success = tracker.dispatch(
// What entity to provide during a single success.
// This is either:
// - `ANY`, which chooses the first tracked entity.
// - `NON_ZERO`, which chooses the first tracked entity that provides a non-zero value.
CommandResponseTracker.ElementType.NON_ZERO,
// The handler for what to do
// Either a `CommandResponseTracker$Dispatch`, `$DispatchWithArg`, or `$DispatchWithArgs`
new CommandResponseTracker.DispatchWithArg<>(
// If there is one match.
// This takes in the object generic, the total value tracked (what's returned to the command), and any additional arguments used.
(entity, totalValue, arg) -> true,
// If there are no or multiple matches.
// This takes in the total number of objects tracked, the total value tracked (what's returned to the command), and any additional arguments used.
(entityCount, totalValue, arg) -> false
),
// Any additional arguments passed to the message handler.
42
);
}
net.minecraft.server.commandsArgProvider- Provides an argument mapping to a specific object.CommandResponseTracker- Tracks all targets of a command and sends any feedback to specific users.
Conversion Tracker
ConversionTracker is a method of handling the conversions of mob from one form to another (e.g. zombie -> drowned, skeleton -> stray), as long as they are entities of the same type. It takes in the entity information along with any necessary storage and values, and manages the behavior until the entity is converted sucessfully, or is reset.
The tracker is typically added as an instance field on the entity itself, then hooked in via tick, addAdditionalSaveData, and readAdditionalSaveData:
// Within some Mob subtype
// Assume we have ExampleEntity extends Mob
// And another ExampleSubEntity extends ExampleEntity
public class ExampleEntity extends Mob {
// For syncing that the entity is being converted.
private static final EntityDataAccessor<Boolean> SUB_CONVERSION_ID = SynchedEntityData.defineId(ExampleEntity.class, EntityDataSerializers.BOOLEAN);
private final ConversionTracker<ExampleEntity> subTracker = new ConversionTracker<>(
// The mob being converted.
// This is used to handle everything related to setting and checking any mob data,
// and eventually calling `Mob#convertTo`.
this,
// The accessor used to sync that the entity is currently being converted.
SUB_CONVERSION_ID,
// The entity this will become after conversion.
() -> EXAMPLE_SUB_ENTITY,
// The level event to run on the client on conversion.
() -> LevelEvent.SOUND_GHAST_FIREBALL,
// The predicate that determines whether the mob can be converted.
// This must remain true throughout the entire affliction and conversion process;
// otherwise the conversion will fail.
this::isAlive,
// The tag key used to store the affliction time on the entity when writing to disk.
"SubAfflictedTime",
// How many ticks the entity needs to be afflicted for before the conversion can start.
600, // 30 seconds
// The tag key used to store the conversion time on the entity when writing to disk.
"SubConversionTime",
// How many ticks the entity takes to convert.
20, // 1 second
// A consumer that is run after the entity has been converted, as a finalization step.
(ExampleSubEntity converted, ServerLevel level) -> {
}
);
// ...
@Override
protected void defineSynchedData(SynchedEntityData.Builder entityData) {
super.defineSynchedData(entityData);
// Register the synced data.
entityData.define(SUB_CONVERSION_ID, false);
}
@Override
public void tick() {
super.tick();
// Tick the tracker.
this.subTracker.tick();
}
@Override
protected void addAdditionalSaveData(ValueOutput output) {
super.addAdditionalSaveData(output);
// Write our tracker data.
this.subTracker.addAdditionalSaveData(output);
}
@Override
protected void readAdditionalSaveData(ValueInput input) {
super.readAdditionalSaveData(input);
// Read the tracker data.
this.subTracker.readAdditionalSaveData(input);
}
}
Note that, given the requirement that the converted entity must be a subtype of the converting entity, this has rather limited use cases (it's the reason why zombie villager -> villager does not use the tracker).
net.minecraft.world.entity.ConversionTracker- A tracker for handling a mob turning into another mob.net.minecraft.world.entity.monster.skeleton.SkeletonisFreezeConverting->ConversionTracker#isConvertingsetFreezeConverting->ConversionTracker#setConvertingdoFreezeConversion->ConversionTracker#doConversion
net.minecraft.world.entity.monster.zombieDrowned#rangedAttackUncertainty,setRangedAttackUncertainty- Handles the uncertainty when making a ranged attack (typically with a trident).ZombiegetConversionSound- The level event to play on conversion.convertsToWhenDrowning- The entity this converts to when drowning.doUnderWaterConversion->ConversionTracker#doConversionconvertToZombieType->ConversionTracker#doConversion
Tag Changes
minecraft:blockblocks_dolphin_jumpblocks_fluid_flowblocks_lava_fire_spreadblocks_motionblocks_motion_in_heightmapblocks_motion_in_heightmap_no_leavesblocks_motion_no_leavescannot_place_basalt_pillar_oncat_does_not_teleport_tocats_can_lie_oncats_can_sit_oncauses_suffocationconcrete_slabsconcrete_stairsconduit_effect_blockconvertable_to_mud->convertible_to_mudcushion_uses_collision_shapedangerous_for_teleportationenderman_does_not_teleport_toentities_can_teleport_toheight_specific_ore_replaceablesice_melts_when_destroyed_abovenether_carver_replaceablesis removedoverworld_carver_replaceablesis removedpoplar_logsrequired_for_poplar_leaf_ambiencesculk_growth_inhibitorsshulker_does_not_teleport_toskullsspeeds_up_zombie_villager_curingturns_into_dirt_pathturns_into_farmlanduncarvablevillager_babies_can_jump_on_bedvillagers_can_sleep_on_bedwashed_away_by_fluidswool_slabswool_stairs
minecraft:damage_typebypasses_cooldownno_wolf_retaliation
minecraft:entity_typecannot_be_dismounted_by_item_usage
minecraft:fluidaxolotl_tries_to_finddolphin_tries_to_findentity_floatablefrog_tries_to_find_land_near
minecraft:itembrewing_fuelis removedbrewing_potion_inputsclonable_mapsconcrete_slabsconcrete_stairscushionsdouses_campfiresextendable_mapsfurnace_fuel_bottom_takeablemushroomsorespoplar_logswool_slabswool_stairs
minecraft:potiondouses_fireextinguishes_entitieshurts_water_sensitive_entitiesrehydrates_axolotls
minecraft:worldgen/biome/has_structureabandoned_camp_bamboo_jungleabandoned_camp_birch_forestabandoned_camp_cherry_groveabandoned_camp_dappled_forestabandoned_camp_flower_forestabandoned_camp_forestabandoned_camp_meadowabandoned_camp_old_growth_birch_forestabandoned_camp_old_growth_pine_taigaabandoned_camp_old_growth_spruce_taigaabandoned_camp_pale_gardenabandoned_camp_savannaabandoned_camp_snowy_taigaabandoned_camp_sparse_jungleabandoned_camp_swampabandoned_camp_taigaabandoned_camp_windswept_forestabandoned_camp_wooded_badlands
minecraft:worldgen/configured_feature->worldgen/featureminecraft:worldgen/structureabandoned_campon_abandoned_camp_bamboo_jungleon_abandoned_camp_birch_foreston_abandoned_camp_cherry_groveon_abandoned_camp_dappled_foreston_abandoned_camp_flower_foreston_abandoned_camp_pale_gardenon_abandoned_camp_swampon_abandoned_camp_windswept_foreston_ancient_city_mapson_desert_pyramid_mapson_jungle_explorer_maps->on_jungle_pyramid_mapson_mineshaft_mapson_ocean_explorer_maps->on_ocean_monument_mapson_ocean_ruin_warm_mapson_swamp_explorer_maps->on_swamp_hut_mapson_trial_chambers_maps->on_burial_trial_chambers_mapson_woodland_explorer_maps->on_woodland_mansion_maps
List of Additions
com.mojang.math.Axisrotate- Rotates a matrix around the given radian angle.rotateDegrees- Rotates a matrix around the given degree angle.
net.minecraft.SharedConstantsDEBUG_CALCULATE_SOLID- A flag that dumps the solidness of blogs to the debugger.DEBUG_ENABLE_FARLANDS- A flag that enables the farlands bug.IS_RENDERDOC_ATTACHED- Whether renderdoc is attached to the running game instance.
net.minecraft.client.resources.language.EmptyTranslationsException- Throws an exception if there is a missing translation for a language.net.minecraft.client.resources.soundsAbstractSoundInstance#soundEvent- The sounds to choose from.SoundInstance#getSoundEvent- The sounds to choose from.
net.minecraft.client.server.IntegratedServersetPersonalGameType,getPersonalGameMode- Handles the host user's game mode.getCustomPermissionLevel- Gets the current permission level for guests, or nothing if pure singleplayer.
net.minecraft.client.sounds.SoundEngine#LOOPING_SOUND_SUBTITLE_INTERVAL_TICKS- The number of ticks of how often to notify new listeners to display the subtitle of a looping sound.net.minecraft.commandsCommandSourceStack$NamesProvider- A provider for the display and text name of the source.SharedSuggestionProvider#getAvailablePostEffects- Returns all available post effects.
net.minecraft.commands.argumentResourceOrIdArgumentfloatProvider,getFloatProvider,$ContextFloatProviderArgument- Float provider arguments.intProvider,getIntProvider,$ContextIntProviderArgument- Int provider arguments.feature,getFeature,$ContextIntProviderArgument- Feature arguments.
SlotSourceArgument- A command argument that specifies a slot source.SwingAnimationArgument- A command argument that specifies a swing animation type.
net.minecraft.commands.arguments.coordinates.LocalCoordinates#apply- Applies the local coordinates to the given vector with the specified rotation.net.minecraft.commands.synchronization.SuggestionProviders#POST_EFFECTS- Suggestions for post effects to select.net.minecraft.coreBlockPoswithinClippedManhattan- Iterates through all positions by manhattan distance within the reach bounds.withinBoxByManhattanDistance- Iterates through all positions by manhattan distance within the box bounds.
CompositeDirection- A composition of multiple directions, with a computed step.Directional- An interface that defines whether something has a direction.PositionAndRotation- An interfaces that defines an object has a position and rotation.Vec3i#differsHorizontally- Whether the passed vector has a different horizontal position.
net.minecraft.dataBlockFamiliesPOPLAR_PLANKS- Poplar variants.WOOL- Wool variants.CONCRETE- Concrete variants.
BlockFamily$Builder#carpet,$Variant#CARPET- Carpet variant for a base block.
net.minecraft.data.recipes.RecipesProvidercarpetBuilder- Creates a carpet recipe.cushionRecipe- Creates a cushion recipe.
net.minecraft.gametest.frameworkGameTestDimensions- The dimensions to test the game within.GameTestHelperrotateEntityWithTest- Rotates the entity relative to the test.useItemOnBlock- Uses an item on the given block, callingItemStack#use.
GameTestInstance#dimension- The dimension to run the test in.TestFunctionLoader#ALL_LOADERS- All registered loaders for test functions.
net.minecraft.network.chat.FilterMask$Type#STREAM_CODEC,streamCodec- Network codecs for the types of chat filters.net.minecraft.network.codec.ByteBufCodecsBIT_SET- A network codec for aBitSet.INSTANT- A network codec for anInstant.fixedBitSet- A network codec for aBitSetwith a certain size.fixedSizeCollection,fixedSizeList- A network codec for a collection with a certain size.
net.minecraft.network.protocol.commonClientboundPostEffectsPacket- A packet sent to the client of what effects to activate.ClientCommonPacketListener#handlePostEffects- Handles when theClientboundPostEffectsPacketis received from the server.
net.minecraft.network.protocol.gameClientboundCustomChatCompletionsPacket$Action#STREAM_CODEC- The network codec for what action to take for the received chat completions.ClientboundMoveEntityPacketunpackOnGround- Unpacks whether the entity is on the ground.unpackStepCount- Unpacks the number of steps the entity has taken.packProperties- Unpacks the entity properties.
ClientboundPlayerInfoUpdatePacket$Action#STREAM_CODEC- The network codec for what action to take when display player information.ClientboundSwingAnimationPacket- A packet sent to the client when the player swings one of their hands.ClientGamePacketListener#handleSwingAnimation- Handles when theClientboundSwingAnimationPacketis received from the server.MovementPacket- A packet that changes the position and/or rotation of an object.ServerboundPlayerActionPacket$Action#CHANGE_DESTROY_DIRECTION- Changes the face that the player is destroying the block from.VecDelta- Defines the delta of a vector either with some kind of stepped movement (e.g., linear, keyframed).VecDeltaCodecencodingPrecisionLoss- Calculates the precision loss during encoding.isDeltaTooBig- Checks whether the delta movement is larger than a short.tryEncode- Attempts to encode the position path movement into a delta vector.
net.minecraft.network.syncher.EntityDataSerializers#DYE_COLOR- Syncs theDyeColorof an entity on change.net.minecraft.resourcesFileToIdConverterprefixMatches- Whether the path of an identifier starts with the file prefix.matches- Whether the identifier matches the file prefix and extension.
net.minecraft.server.MinecraftServer#forceGameMode,setForceGameMode- Handles forcing the game mode of all players.net.minecraft.server.commandsComputeCommand- A command that allows computingintandfloatproviders.LootContextSources- A helper for setting the context sources to aLootParams$Builder.PostEffectCommand- A command for modifying the post effects on the camera.
net.minecraft.server.commands.itemBlockItemAccessor- An accessor that modifies the items in a block.EntityItemAccessor- An accessor that modifies the items held by an entity.ItemAccessor- An accessor for modifying items stored on an object.
net.minecraft.server.levelParticleStatus#STREAM_CODEC- The network codec for particle settings.ServerChunkCache#sendToTrackingPlayersFiltered- Sends packets to all players that match the predicate.ServerLevel#uncachedBiomeResolver- Returns a biome resolver that uses a non-cached sampler.
net.minecraft.server.network.ServerCommandSuggestionsProvider- A suggestions provider on the server for received command completions.net.minecraft.server.notifications.NotificationService#worldUpgradeStarted,worldUpgradeProgress,worldUpgradeFinished,worldUpgradeFailed- Notifications sent when upgrading a world.net.minecraft.utilARGBcolorFromVector3f- Converts an RGB vector to anint.colorFromVector4f- Converts an ARGB vector to anint.
BitStorage#fill- Sets all bit of the storage to the specified value.BlockUtil#MAX_POSITION_DIFFERENCE_PACKING_RADIUS,clampedPackDifferenceInPosition,packDifferenceInPosition,unpackDifferenceInPosition- Handles packing the difference between two positions into a single integer, such as for running a level event when an enderman teleports.CommonLinks$ExtensionReference- An enum representing the reference to extend a realm.ExtraCodecs#RGB_COLOR_VEC3_CODEC,ARGB_COLOR_VEC4_CODEC,STRING_RGB_VEC3_COLOR,STRING_ARGB_VEC4_COLOR- Color codecs.Mthlerp2- Performs two levels of linear interpolation.lerp3- Performs three levels of linear interpolation.
Prediction- An enum that represents the calculation should be predicted by the client or handled server only.ProblemReporter$CollectionReferencePathElement- A path element of aTagKey.$Collector#hasFatalProblems- If the report contains a problem that is considered fatal when attempting to load and use the data.$Problem#isFatal- Whether the problem prevents loading or usage of the data.
StaticCache2D#map,$MappingFunction- Maps each XZ coordinate value to a new value.UtilMILLIS_PER_SECOND- The number of milliseconds in a second.toMillis- Converts seconds to milliseconds, flooring to the closest millisecond.isAppleSiliconMac- If the renderer string is using Apple silicon.
net.minecraft.util.random.WeightedList#addAll- Add all elements from another weighted list to this one.net.minecraft.util.worldupdate.UpgradeProgress#notifications- The notification service.net.minecraft.worldInteractionHand#asArm- Gets the correctHumanoidArmbased on the user's main arm.InteractionResult$Success#shouldSwing- Whether the arm performing the interaction should swing.
net.minecraft.world.entityEntityTAG_INVULNERABLE_TIME- A tag for how long an entity is invulnerable for.interpolationHandler- A handler for interpolating between positions on a path.commonTick- A tick method that's always executed and cannot be modified before the entity's actual tick logic.recordMovement- Records the movement received, typically for client simulation.isInFloatableFluid- Whether the entity is a fluid that it can float in.pushFromExplosion- Pushes an entity due to an explosion.calculateViewQuaternion- Calculates the quanternion for where the entity is looking.postDataManipulated- Runs after the entity's data is manipulated from theEntityDataAccessor.doTeamsAllowDamage- Whether teams can damage each other.onInterpolationStart,createInterpolationHandler- Creates the interpolation handler used for movement.getLookQuaternion- Gets the quanternion for where the entity is looking.projectileReceivesSideEffectsOnHit- Whether the projectile performs additional actions on hitting an entity.isPermanentlyInvulnerable- If the entity can never be hurt.isTemporarilyInvulnerable- If the entity is currently invulnerable for a set period of time.getInterpolatedBoundingBox- Gets the entity's bounding box interpolated by some partial tick.getMoveSimulationType- Gets how the entity's movements are simulated.storePositionAndRotation,getClientPositionAndRotation,getClientPosition- Handles getting the entity's position and/or rotation, typically on the client.setInvulnerableTime,getInvulnerableTime- Handles temporary invulnerability.
EntityEvent$Value- An annotation that represents a value as being an entity event.EntityTypeNO_UPDATE_INTERVAL,$Builder#noUpdateInterval- An entity that never updates on the client.hasUpdateInterval- Whether the entity updates on the client.$Builder#dontTrackDeltas- Whether not to track the delta movements of an entity.
InterpolationHandler#interpolationTracker- A tracker for the current interpolated value.InterpolationTracker- A tracker for the current interpolated value.LivingEntitydamageCooldownTime- How long to wait between receiving damage.wasHurtRecently- Whether the entity's hurt timer is positive.isInFluidDeeperThan- If the fluid height is greater than some given value.isSwinging- If the entity is swinging its arm.canRandomlyTeleportTo- Whether this entity can randomly teleport to the given location.$SwingDescription- A record that contains information about the hand swinging.
MoverType#isServerAndClientSimulated- If the movement is simulated on both the client and server.MoveSimulationType- An enum containing the types of movement simulation (e.g., both client and server, only on the side running the logical server, etc.).PositionPath- A path of movements between two positions.PositionStep- A step representing some location on a path made at a certain tick offset.SteppedInterpolationHandler- An interpolation handler that moves between path segments.SteppedInterpolationTracker- An interpolation tracker that handles moving between path segments.UpdateInterval- Handles when an entity should be next updated.
net.minecraft.world.entity.decorationBlockAttachedEntityTAG_BLOCK_POS- A tag containing the block position name.tickAtCheckInterval- Runs once every X ticks (by default 100).onKilled- What to do when the entity is killed.
Cushion- A cushion entity.RangedAttackMob#rangedAttackUncertainty- Returns the scalar affecting a mob's accuracy.
net.minecraft.world.entity.monster.zombie.Drowned#rangedAttackUncertainty,setRangedAttackUncertainty- Handles the uncertainty when making a ranged attack (typically with a trident).net.minecraft.world.entity.player.ChatVisibility#STREAM_CODEC- The network codec.net.minecraft.world.entity.projectile.ProjectilecanBreakBlockInAdventureMode- Whether the projectile can break a block while the world game mode is adventure mode.onRedirectProjectile- What to do when a projectile is redirected via deflection.
net.minecraft.world.inventoryAbstractContainerMenuCONTAINER_CLICK_PRIMARY- A constant representing the player clicked in the inventory using the attack button.CONTAINER_CLICK_SECONDARY- A constant representing the player clicked in the inventory using the use item button.
MerchantMenu#updateSellItem- Updates the item being offered for a trade.SlotRanges#tryRead,read- Parses the slot range from its string identifier.
net.minecraft.world.itemArrayItemProvider- A provider iterating through an array of items, providing a copy of each to use.CushionItem- An item for a cushion entity.ItemProvider- An accessor that iterates through some backing item holder.MapItem#applyNewSavedData- Creates new saved data for the map and stores it as a component on the item.SwingAnimationType#byName- Gets the animation type by its name, otherwise defaulting to the provided value.
net.minecraft.world.levelBaseSpawner#setEntityData- Sets the data of the spawned entity.EmptyStructureManager- AStructureManagerthat generates nothing.GameType#OPTIONAL_STREAM_CODEC- A codec that returns a game type from an integer when present.Level#getRelativeTickSpeed- Gets the tick speed relative to the game's normal 20 ticks per second.Spawner#setEntityData- Sets the data of the spawned entity.
net.minecraft.world.level.block.LevelEvent$Value- An annotation that marks anintas representing a level event id.net.minecraft.world.level.block.entity.trialspawner.TrialSpawner$FullConfig#overrideEntityData- Sets the entity data of the trial spawner.net.minecraft.world.level.block.sounds.AmbientLeavesBlockSoundPlayer- A record containing the data to play ambient leaves sounds on the client.net.minecraft.world.level.block.state.SolidDebugger- A debugger for checking and logging the solidness of blocks.net.minecraft.world.level.blockscanBlockMatcher- A helper that returns a list of block positions, typically provided to the matcher, by someBlockStateorBlockPospredicate.BlockScanUtils- A utility for returning if a block was found that causes the scan to abort.BlockStateConsumer- A functional interface that, given aBlockStateandBlockPos, whether the search should continue or abort.BoxBlockMatcher- A matcher that checks the positions within a given box.FilteredSectionCache- A cache for quickly retrieving chunk sections that has the matchingBlockStatepredicate.OrderedBlockMatcher- A matcher that checks the positions in the order provided by the passed inIterable.
net.minecraft.world.level.dimension.DimensionDefaults#*_CELL_SIZE_*- Defines the size of a cell in blocks in each direction during generation.net.minecraft.world.level.dimension.end.EnderDragonFight#getPodiumLocation- Returns the end podium location offset by the givenBlockPos.net.minecraft.world.level.material.FluidState#getHeightForCamera- Returns the height of the fluid for camera positioning by always returning1if the source fluid has a sturdy block above it.net.minecraft.world.level.pathfinder.PathType#STREAM_CODEC- The network codec.net.minecraft.world.level.storage.PrimaryLevelData#writeVersionHistory- Writes the version history of the world.net.minecraft.world.physAABB#nextDeflated- Returns the deflated bounds of the AABB, moving to the next adjacent value.BlockHitResult#STREAM_CODEC- The network codec.Vec3#atCenterOfWithY- Centers theVec3iwith the given Y position.
List of Changes
com.mojang.math.Axisis no longer a functional interfaceofnow takes in aVector3fcinstead of aVector3f
net.minecraft.client.resources.langauage.LanguageManagernow takes in theMinecraftinstancenet.minecraft.client.resources.soundsSound#getAttenuationDistancenow has na overload that takes in thefloatvolumeSoundInstance#resolve->getOrResolveUnderwaterAmbientSoundInstancesis removed$SubSound->$UnderLiquidSubSound$UnderwaterAmbientSoundInstance->UnderwaterLiquidAmbientSoundInstance
net.minecraft.client.server.IntegratedServercommandsAllowedForOtherPlayers->getGuestCommandAccesssetCommandsAllowedForOtherPlayers->setGuestCommandAccess
net.minecraft.commandsCommandSourceStackno longer takes in theStringtext name, and can optionally decide whether to provide theComponentdisplay nameSharedSuggestionProvidersuggestRegistryElementsnow specifies a genericEfor the registry object type, now taking in aPredicatefilterlistSuggestionsnow specifies a genericEfor the registry object type,now optionally taking in aPredicatefilter
net.minecraft.commands.argumentsArgumentSignaturesArgumentSignatures(FriendlyByteBuf),#writereplaced bySTREAM_CODEC$Entry(FriendlyByteBuf),$Entry#writereplaced by$Entry#STREAM_CODEC
ResourceKeyArgument,#keycan now take in aPredicatefilter
net.minecraft.coreDirectionnow implementsDirectionalDirection8->CompositeDirection$Direction8
net.minecraft.gametest.frameworkBuiltinTestFunctionsnow implementsTestFunctionLoaderinstead of extendingGameTestBatchnow takes in theResourceKeyfor the dimension to test inGameTestBatchFactorydivideIntoBatchesnow takes in theMinecraftServerinstead of theServerLeveltoGameTestBatchnow takes in theResourceKeyfor the dimension to test in
GameTestRunnernow takes in theMinecraftServerinstead of theServerLevel$Builder#fromBatches,fromInfonow take in theMinecraftServerinstead of theServerLevel$StructureSpawner#onBatchStartnow takes in theMinecraftServerinstead of theServerLevel
StructureGridSpawnernow takes in aFunction<ResourceKey<Level>, BlockPosfor the first test instead of the rawBlockPosTestDatanow takes in theResourceKeyfor the dimension to test inTestFunctionLoaderis now aninterfacefrom aclassTestPosFinder#findTestPosnow returns a stream ofGlobalPosinstead ofBlockPos
net.minecraft.network.FriendlyByteBuf#readFixedBitSet,writeFixedBitSetnow have static overloads that take in theByteBufnet.minecraft.network.chatFilterMask#read,writereplaced bySTREAM_CODECLastSeenMessages$Packed(FriendlyByteBuf),#writereplaced bySTREAM_CODEC$Update(FriendlyByteBuf),#writereplaced bySTREAM_CODEC
MessageSignature#read,writereplaced bySTREAM_CODEC- Original methods are now
privatefrompublic $Packed$#read,writereplaced bySTREAM_CODEC- Original methods are now
privatefrompublic
- Original methods are now
- Original methods are now
RemoteChatSession$Data#read,writereplaced bySTREAM_CODECResolutionContextnow takes in anintresolution limit and aMutableIntfor the resolved countSignedMessageBody$Packed(FriendlyByteBuf),#writereplaced bySTREAM_CODEC
net.minecraft.network.codec.StreamCodec#compositenow has overloads that take up to fourteen elements.net.minecraft.network.protocol.common.ClientboundUpdateTagsPacketis now a recordnet.minecraft.network.protocol.configuration.ClientboundUpdateEnabledFeaturesPacket#STREAM_CODECcan now work with aByteBufnet.minecraft.network.protocol.gameClientboundAnimatePacket#SWING_MAIN_HAND,SWING_OFF_HANDnow handled byClientboundSwingAnimationPacketClientboundChunksBiomesPacket#STREAM_CODECcan now work with aByteBuf$ChunkBiomeData(FriendlyByteBuf),#writereplaced bySTREAM_CODEC
ClientboundCustomChatCompletionsPacket#STREAM_CODECcan now work with aByteBufClientboundDeleteChatPacket#STREAM_CODECcan now work with aByteBufClientboundEntityPositionSyncPacketnow implementsMovementPacketinstead ofPacket- The constructor now takes in a
PositionPathandfloats for the xy rotation instaed of aPositionMoveRotation ofnow has an overload that specifies thePositionPath
- The constructor now takes in a
ClientboundExplodePacketnow takes in abooleanfor whether to play a soundClientboundLevelChunkPacketData(FriendlyByteBuf, int, int),#writereplaced bySTREAM_CODECgetBlockEntitiesTagsConsumerreplaced byforEachBlockEntityTag, not one-to-one
ClientboundLevelChunkWithLightPacketis now a recordClientboundLevelParticlesPacketis now a record- The constructor now takes in a
$RandomizationType $RandomizationType- How the particle should move when spawned.
- The constructor now takes in a
ClientboundLightUpdatePacketis now a recordClientboundLightUpdatePacketDatais now a recordClientboundMoveEntityPacketnow implementsMovementPacketinstead ofPacket- The constructor now takes in a
VecDeltainstead of threeshorts xa,ya,zamerged intoVecDeltagetXa,getYa,getZamerged intogetPositionDelta$Posnow takes in aVecDeltainstead of threeshorts$PosRotnow takes in aVecDeltainstead of threeshorts
- The constructor now takes in a
ClientboundMoveVehiclePacketnow only takes in aPositionAndRotationClientboundOpenBookPacketis now a recordClientboundOpenSignEditorPacketis now a recordClientboundPlayerChatPacketnow usesOptionals for the signature and unsigned content instead of nullablesClientboundPlayerInfoRemovePacket#STREAM_CODECcan now work with aByteBufClientboundRemoveEntitiesPacketis now a recordCommonPlayerSpawnInfonow uses anOptionalfor previous game type instead of a nullableCommonPlayerSpawnInfo(FriendlyByteBuf),#writereplaced bySTREAM_CODEC
ServerboundAcceptTeleportationPacketis now a record- The constructor now takes in the
doublexyz andfloatxy rotation
- The constructor now takes in the
ServerboundChatCommandSignedPacket#STREAM_CODECcan now work with aByteBufServerboundChatPacketnow uses anOptionalfor signature instead of a nullableServerboundChatSessionUpdatePacket#STREAM_CODECcan now work with aByteBufServerboundCommandSuggestionPacketis now a recordServerboundMoveVehiclePacketnow takes in aPositionAndRotationinstead of aVec3potion andfloatxy rotationsServerboundSignUpdatePacketis now a record- The constructor now takes in a
SignTextSlotinstead of abooleanfor front text
- The constructor now takes in a
ServerboundSwingPacket->ServerboundPunchPacketServerboundUseItemOnPacketis now a recordServerboundUseItemPacketis now a recordServerGamePacketListener#handleAnimate->handlePunch
net.minecraft.server.MinecraftServerpublishServerno longer takes in theGameTypegetStructureManager->getStructureTemplateManager
net.minecraft.server.commands.ItemCommands->.item.ItemCommandsnet.minecraft.server.commands.dataBlockDataAccessor#PROVIDERis now aArgProvider$FactoryDatacommands#ALL_PROVIDERS,TARGET_PROVIDERS,SOURCE_PROVIDERSare now lists ofArgProvider$FactorysEntityDataAccessor#PROVIDERis now aArgProvider$FactoryStorageDataAccessor#PROVIDERis now aArgProvider$Factory
net.minecraft.server.levelChunkMapno longer takes in a suppliedSavedDataStoragefor the overworld$TracketEntitynow takes in anUpdateIntervalinsetad of anint
ServerChunkCacheno longer takes in a suppliedSavedDataStoragefor the overworldServerEntitynow takes in anUpdateIntervalinstead of anintServerLevelgetStructureManager->getStructureTemplateManagersendParticlesnow have overloads that takes in aClientboundLevelParticlesPacket$RandomizationTypefindNearestMapStructurenow has an overload that takes in theHolderSet<Structure>instead of theResourceKey
ServerPlayer#getWardenSpawnTrackernow returns the rawWardenSpawnTrackerinstead of an optional
net.minecraft.tags.TagNetworkSerialization$NetworkPayloadis now a recordread,writereplaced bySTREAM_CODEC
net.minecraft.utilAbortableIterationConsumer$Continuation->ContinuationabortIf- Returns an abort if the providedbooleanis true.continueIf- Returns a continue if the providedbooleanis true.
ARGBmultiplynow has overloads that works withVector3fcs orVector4fcsaddRgbnow has overloads that works withVector3fcs orVector4fcssubtractRgbnow has overloads that works withVector3fcs orVector4fcsscaleRGBnow has overloads that works withVector3fcs orVector4fcsgreyscalenow has overloads that works withVector3fcs orVector4fcsalphaBlendnow has overloads that works withVector3fcs orVector4fcssrgbLerpnow has overloads that works withVector3fcs orVector4fcs
CommonLinksEXTEND_REALMS_LINKis now aURIinstead of aStringextendRealmsnow returns aURI, taking in an$ExtensionReferenceinstead of abooleanfor a trial
ExtraCodecs#relaiveNormalizedSubPathCodec->relativeNormalizedSubPathCodecMthsmoothstep,smoothstepDerivativenow work withfloats instead ofdoubleslengthSquarednow has an overload that works withfloatslengthnow has an overload that works withfloats
Utiljoinnow takes inCollections instead ofLists$OSopenUri->Blaze3D#openUriopenPath->Blaze3D#openPath
net.minecraft.util.debug.DebugBrainDump(FriendlyByteBuf),#writemerged intoSTREAM_CODECnet.minecraft.util.filefix.FileFixerUpper#swapInFixedWorldnow takes in theUpgradeProgressnet.minecraft.util.worldupdate.UpgradeProgressnow has an overload that takes in theNotificationServicenet.minecraft.world.InteractionResult$SwingSourceCLIENT->PREDICTEDSERVER->SERVER_ONLY
net.minecraft.world.entityEntityhurtMarked->syncVelocityinvulnerableTimeis nowprivatefrompublicinsideEffectCollectoris nowprotectedfromprivatecalculateViewVectoris nowstaticinstead offinalcalculateUpVectoris nowstaticinstead offinalmoveOrInterpolateTonow has an overload that takes in thePositionPathinstead of aVec3setInvulnerable->setPermanentlyInvulnerablecanSimulateMovementis nowfinal
EntityFluidInteractionupdatenow returns if the entity was pushed by a fluid$Tracker->$CurrentAccumulator$Trackernow just tracks the height of a given fluid, which can be reset via$Tracker#resetaccumulateCurrent->accumulateapplyCurrentTo->applyTo
EntityTypenow takes in abooleanfor whether to track an entity's delta movementgetSpawnAABBnow has an overload that takes in aVec3
InterpolationHandleris now aninterfacefrom aclass- It's original implementation has been moved to
AbstractInterpolationHandlerandLinearInterpolationHandler setInterpolationLength->LinearInterpolationHandler#setInterpolationLengthposition,yRot,xRotmerged intotarget
- It's original implementation has been moved to
LivingEntityINVULNERABLE_DURATION->DAMAGE_COOLDOWN_DURATIONswinging,swiningArm,swingTime,oAttackAnim,attackAnimmerged intoswingState, nowprivatefrompublicinterpolationreplaced byEntity#interpolationHandlerdropnow takes in aPredictioninstead of a randombooleangetVisibilityPercentnow takes in aServerLevelgetLastDamageSourcenow has an overload that takes in a tick timeout for when the damage source was receivedswing(InteractionHand)->swingAndResetAttackStrength, now taking in aSwingAnimationand abooleanfor whether to sync the swinging motion- The original implementation has been moved to
Mob#swingForAttackorMob#swing(InteractionHand, SwingAnimation)
- The original implementation has been moved to
swing(InteractionHand, boolean)now takes in aSwingAnimation, returning whether the entity has made a successful swingupdateSwingTime->$SwingState#tickgetAttackAnimreplaced bygetCurrentSwingorgetSwingAnimationcreateItemStackToDropis nowpublicfromprivaterandomTeleportnow takes in aTagKeyor aPredicateof invalidBlockStates to teleport tostartSleepingnow returns whether the entity has fallen asleeponEquippedItemBrokennow takes in anItemStackinstead of anItemblockUsingItem,blockedByItemnow takes in abooleanfor whether the damage was fully blocked
Mob#clampHeadRotationToBodyis nowpublicfromprotected
net.minecraft.world.entity.ai.behaviorGoAndGiveItemsToTargetno longer rquires the entity to be anInventoryCarrier- The constructor now takes in the cooldown
MemoryModuleType, how long to cooldown for, and aPredicatefor whether it can accept the item $ItemThrower#onItemThrown->throwItem, no longer taking in theItemStack, instead taking aVec3instead of theBlockPos, not one-to-one
- The constructor now takes in the cooldown
Swimnow has an overload that takes in the fluidTagKeyTryFindLandNearWater->TryFindLandNearLiquid, not one-to-oneTryFindLiquid->TryFindWater, not one-to-one
net.minecraft.world.entity.ai.goalCatLieOnBedGoal->CatLieOnBlockGoal, not one-to-oneFloatGoalnow has an overload that takes in the fluidTagKeyPanicGoal#lookForWaternow takes in aLevelReaderinstead of theBlockGetterTryFindWaterGoal->TryFindLiquidGoal, not one-to-one
net.minecraft.world.entity.ai.gossip.GossipContainer#transferFromnow returns the number of new gossips.net.minecraft.world.entity.ai.navigation.PathNavigation#moveTonow has an overload that takes in anintreach rangenet.minecraft.world.entity.decorationArmorStand#killnow takes in theEntitythe kill is attributed toBlockAttachedEntity#killnow takes in theEntitythe kill is attributed to
net.minecraft.world.entity.monsterEnderMan->Enderman, not one-to-oneShulker#MAX_TELEPORT_DISTANCEis nowpublicfromprivate
net.minecraft.world.entity.monster.cubemob.AbstractCubeMobsetcubeMobHealth->setCubeMobHealthisDealsDamage->canDealDamage
net.minecraft.world.entity.npc.villager.Villager#FOOD_POINTSreplaced byVillagerFoodnet.minecraft.world.entity.playerInventoryclearOrCountMatchingItemsnow takes in abooleanfor whether to count the items only without clearingplaceItemBackInInventorynow takes in aPrediction
PlayeropenTextEditnow takes in aSignTextSlotinstead of abooleanstartSleepInBednow takes in anAbstractBedBlock, theBlockState, and theBedRule
ProfilePublicKey$Data(FriendlyByteBuf),#writereplaed bySTREAM_CODEC
net.minecraft.world.entity.projectileProjectiledeflectcan now take in a powerdoubleorVec3onItemBreaknow takes in anItemStackinstead of anItemmayBreaknow takes in aBlockPos
ProjectileDeflection#deflectnow takes in theVec3powerProjectileUtil#getManyEntityHitResultnow takes abooleanfo whether to use the projected surface hit, or the outside hit location
net.minecraft.world.entity.vehicle.boat.AbstractBoat#clampRotationnow returns the rotation differencenet.minecraft.world.entity.vehicle.minecartMinecartBehavior#getInerpolationreplaced byonInterpolationStart, not one-to-oneOldMinecartBehavior#onInterpolationreplaced byonInterpolationStart, not one-to-one
net.minecraft.world.itemHangingSignItemnow extendsStandingAndWallBlockItemItemStackhurtAndBreaknow takes in aConsumer<ItemStack>instead of aConsumer<Item>on breakaddToTooltipnow has an overload that takes in aTooltipProvider$GettergetSwingAnimationsplit intogetAttackAnimation,getInteractAnimation
ItemStackTemplate#fromNonEmptyStacknow has an overload that takes in a new countintProjectileItem$DispenseConfignow takes in anOptional<Integer>instead of anOptonalIntfor overriding the dispenser level eventSignApplicator#tryApplyToSignnow takes in aSignTextSlotinstead of abooleanfor whether it is front text
net.minecraft.world.item.enchantmentConditionalEffectnow takes in a holderLootItemConditioninstead of the raw condition for the requirementsEnchantedItemInUsenow takes in anItemStackconsumer instead of anItemon breakEnchantmentHelperdoPostAttackEffectsWithItemSourceOnBreaknow takes in anItemStackconsumer instead of anItemon breakonProjectileSpawnednow takes in anItemStackconsumer instead of anItemon breakonHitBlocknow takes in anItemStackconsumer instead of anItemon break
net.minecraft.world.item.tradingTradeRebalanceVillagerTrades#registernow returns nothingTradeSets#registernow returns nothingVillagerTrades#registernow returns nothing
net.minecraft.world.levelLevelplaySoundnow has an overload that takes in aHolder<SoundEvent>instead of the raw soundcreateFireworksnow takes in abooleanfor whether to play a soundLevelsendBlockAndUpdate->LevelWriter#setBlockAndUpdate
LevelReadernow implementsBiomeResolverinstead ofBiomeManager$NoiseBiomeSourcefindBlocksIn,findBlocksInBoxByManhattanDistance,findBlocksInManhattan- Returns a matcher looking for blocks in the specified range in the given order.
NaturalSpawnercreateStatenow takes in aServerLevelinstead of an iterable ofEntitysspawnMobsForChunkGenerationnow takes in the sourceBlockPosinstead of a holderBiome$SpawnPredicate#testnow takes in aServerLevel
StructureManagerstartsForStructurenow takes inints for the XZ coordinates instead of aChunkPosorSectionPosgetStartForStructure,setStartForStructure,addReferenceForStructureno longer takes in theSectionPosgetStructureAtnow has an overload that takes in a holderStructureinstead of the raw structuregetStructureWithPieceAtnow takes inints for the XYZ coordinates instead of aBlockPosstructureHasPieceAtnow has an overload that takes inints for the XYZ coordinates instead of aBlockPosgetAllStructuresAtnow has an overload that takes inints for the XYZ coordinates instead of aBlockPos
net.minecraft.world.level.block.entity.trialspawnerTrialSpawner#overrideEntityToSpawnnow has an overload that takes inTypedEntityDataisntead of theEntityTypeTrialSpawnerConfig#withSpawningnow has an overload that takes inTypedEntityDataisntead of theEntityType
net.minecraft.world.level.block.state.StateHolder#NAME_TAGreplaced byID_TAGnet.minecraft.world.level.chunk.storage.SerializableChunkDatano longer takes in along[]for the carving masknet.minecraft.world.level.material.PushReactionNORMAL->PUSH_PULLDESTROY->POPPEDBLOCK->IMMOVEABLEIGNORE->IGNORE_ENTITYPUSH_ONLY->PUSH
net.minecraft.world.level.pathfinderNode#writeToStream,createFromStream,readContents, replaced byDEBUG_STREAM_CODEC,createDebugStreamCodecPathSTREAM_CODECreplaced byDEBUG_STREAM_CODEC$DebugDatanow takes in lists instead of arrays ofNodesread,writemerged intoSTREAM_CODEC
Target#createFromStreamreplaced byDEBUG_STREAM_CODEC
net.minecraft.world.level.portal.PortalShape#FRAMEis nowpublicfromprivatenet.minecraft.world.level.saveddata.maps.MapDecorationTypeno longer takes in the map colorintorbooleanfor if it has an exploration elementnet.minecraft.world.timeline.Timelines#NIGHT_FOG_COLOR_MULTIPLIER_START,NIGHT_FOG_COLOR_MULTIPLIER_ENDmerged intoNIGHT_FOG_COLOR_MULTIPLIER, not one-to-one
List of Removals
net.minecraft.SharedConstantsDEBUG_CARVERSDEBUG_PREFER_WAYLAND
net.minecraft.client.server.IntegratedServer#getGameTypeForOtherPlayers,setGameTypeForOtherPlayers,applyGameTypeToPlayersnet.minecraft.commands.argumentsResourceArgument#getConfiguredFeature,getStructure,getEntityTypeResourceKeyArgument#getConfiguredFeature
net.minecraft.core.BlockPosBlockPos(Vec3i)squareOutSouthEastfindClosestMatchwithinManhattanStream
net.minecraft.nbt.NbtUtilswriteFluidStateprettyPrint
net.minecraft.networkConnection#setIntendedProfileId,getIntendedProfileIdFriendlyByteBuflimitValuereadCollection,writeCollectionreadListreadIntIdList,writeIntIdListreadMap,writeMapreadInstant,writeInstantreadPublicKey,writePublicKeyreadBlockHitResult,writeBlockHitResult
net.minecraft.server.level.ChunkMap#getStorageNamenet.minecraft.server.network.ServerConnectionListener#acceptChannelnet.minecraft.server.players.PlayerList#setAllowCommandsForAllPlayers,isAllowCommandsForAllPlayersnet.minecraft.utilKeyDispatchDataCodecUtil$OS#openFile,getOpenUriArguments
net.minecraft.world.entity.ai.behavior.Swim#shouldSwimnet.minecraft.world.entity.ai.memory.MemoryModuleType#IS_TEMPTEDnet.minecraft.world.entity.npc.villager.Villager#assignProfessionWhenSpawnednet.minecraft.world.entity.player.Playerdrop(ItemStack, boolean)awardRecipesByKey,resetRecipesgetWardenSpawnTracker
net.minecraft.world.itemBedItemBlockItem#updateCustomBlockEntityTag
net.minecraft.world.levelGameType#getNullableId,byNullableIdStructureManager#hasAnyStructureAt
net.minecraft.world.level.saveddata.mapsMapDecorationType#NO_MAP_COLOR,hasMapColorMapItemSavedData#isExplorationMap
net.minecraft.world.phys.Vec3#applyLocalCoordinatesToRotation,addLocalCoordinates